Author Topic: Generic Clock sam d  (Read 3893 times)

0 Members and 1 Guest are viewing this topic.

Offline losstTopic starter

  • Contributor
  • Posts: 21
  • Country: dz
Generic Clock sam d
« on: September 19, 2016, 04:13:12 pm »
Hello everybody,

I like to have some clarification concerning the clocks used on series microcontrollers  SAMD D from Atmel .
I'd like to know why there is as many clock and how are they configured it there huge differences between Generic clock generator 0, 1, 2?
I will also need to know if during the configuration modules in a project, use the same type of clock?
Faced with all these clocks, I am lost

Thank you
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Generic Clock sam d
« Reply #1 on: September 19, 2016, 04:49:12 pm »
I'd like to know why there is as many clock and how are they configured it there huge differences between Generic clock generator 0, 1, 2?
What are the differences? The only difference that I know of is number of bits in the prescaler. And that's probably to save on hardware while still providing enough flexibility.

There are different clock sources (Xtals, RC oscillators, PLLs, etc), those will be present on any MCU. SAM D adds flexibility of being able to route any of those clock sources to one of clock generators (possibly prescaling it). And peripherals attach to clock generators.

I will also need to know if during the configuration modules in a project, use the same type of clock?
You can use the same clock, if this works for your project. A lot of project require more flexible configuration and SAM D lets you do that.
Alex
 

Offline losstTopic starter

  • Contributor
  • Posts: 21
  • Country: dz
Re: Generic Clock sam d
« Reply #2 on: September 19, 2016, 04:59:58 pm »
If I have a XOSC32 oscillator on PA08 and PA09 pines , then it is possible for me to use it for all my modules?
So I can use it to initialize the system and replace the generic clocks as in this initialization using XOSC32K ?
For example in :
Code: [Select]
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(RTC_GCLK_ID) |
GCLK_CLKCTRL_CLKEN |
GCLK_CLKCTRL_GEN_GCLK0;  <==HERE


But do I keep them clean clocks to each module such RTC_GCLK_ID?

But on the Atmel Studio software is it possible to get the frequency value and the period of the clocks in one place?
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Generic Clock sam d
« Reply #3 on: September 19, 2016, 05:08:06 pm »
If I have a XOSC32 oscillator on PA08 and PA09 pines , then it is possible for me to use it for all my modules?
It is possible, but you really should not do this. You will slow down your whole system to 32 kHz. That's like 100x slower than first processors :)

But do I keep them clean clocks to each module such RTC_GCLK_ID?
I don't understand what do you mean here.

It goes like this. Each and all peripherals can use any of the GCLK[n] generators. So total number of frequencies used in the system is limited to number of GCLKs. But the most complex system I've seen used only 3, so you have plenty.

Each GCLK[n] can have one of many clock sources as an input.

A system configuration may look like this, for example:
1. Internal RC [8 Mhz] -> GCLK[0] -> all peripherals that need to run fast.
2. Xosc32 ->  GCLK[1] -> RTC for accurate time-keeping.
3. Internal RC [8 Mhz] / divided by 3 -> GCLK[2]  -> some weird peripheral that needs 2.666 MHz clock.
Alex
 

Offline losstTopic starter

  • Contributor
  • Posts: 21
  • Country: dz
Re: Generic Clock sam d
« Reply #4 on: September 19, 2016, 05:27:16 pm »
The RTC for accurate time-keeping must use GCLK[1].
But to use this clock I need to configure the XOSC32K before because when I change the configuration GCLK
  • by GCLK [1] the RTC module doesn't work
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Generic Clock sam d
« Reply #5 on: September 19, 2016, 05:31:22 pm »
The RTC for accurate time-keeping must use GCLK[1].
Why do you think so? RTC is just a weird counter designed around human understanding of time, it can be clocked from any clock you like. It will give you accurate time if you clock it from 32kHz.

Here is a quote from the datasheet:
Quote
The RTC can also be clocked from other sources, selectable through the Generic Clock module (GCLK).

But to use this clock I need to configure the XOSC32K before
Yes, you always need to make sure that clock is there before you try to use it. This is kind of logical, all other MCU do it exact same way.

because when I change the configuration GCLK
  • by GCLK [1] the RTC module doesn't work
I don't understand this.
Alex
 

Offline losstTopic starter

  • Contributor
  • Posts: 21
  • Country: dz
Re: Generic Clock sam d
« Reply #6 on: September 19, 2016, 05:41:02 pm »
Yes, but in my case the clock isn't there so for me it's not possible to use the GCLK[1] and I fear that this is the GCLK clock (0) is the source of a strange phenomenon in the program. This is why, I would like to know how to configure a clock GCLK (1) because I have always use the GCLK (0)
« Last Edit: September 19, 2016, 05:42:44 pm by losst »
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Generic Clock sam d
« Reply #7 on: September 19, 2016, 05:42:37 pm »
You are mixing things up. If clock is not there, then enable it and make sure it is there.
Alex
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Generic Clock sam d
« Reply #8 on: September 19, 2016, 05:47:02 pm »
Also, for testing just use ULP32K. It is always there and always enabled.

I don't know what board you are using, but D10 Xplained Mini does not have 32 kHz crystal.
Alex
 

Offline losstTopic starter

  • Contributor
  • Posts: 21
  • Country: dz
Re: Generic Clock sam d
« Reply #9 on: September 19, 2016, 05:56:01 pm »
Well I explain my problem:
I initialized the system clock using the function:
Code: [Select]
void sys_init(void)
{
SYSCTRL->OSC8M.bit.PRESC = 0;

// Enable interrupts
asm volatile ("cpsie i");
}
This means that the clock of 8 MHz.

Then in the PSTN module I use GCLK
  • therefore 8 MHz and a divider 256 therefore the frequency is about 32kHz and with RTC-> MODE0.COMP
  • reg = 1000; every second I make an interruption with RTC-> = MODE0.INTENSET.reg RTC_MODE0_INTENSET_CMP0;:
Code: [Select]
void init_RTCvoid)
{
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN(1) |
GCLK_CLKCTRL_CLKEN |
GCLK_CLKCTRL_ID(RTC_GCLK_ID);

RTC->MODE0.CTRL.reg = RTC_MODE0_CTRL_SWRST;
while (RTC->MODE0.CTRL.bit.SWRST);
while(RTC->MODE0.STATUS.bit.SYNCBUSY);

RTC->MODE0.CTRL.reg = RTC_MODE0_CTRL_MODE_COUNT32;
while(RTC->MODE0.STATUS.bit.SYNCBUSY);

RTC->MODE0.CTRL.reg |= RTC_MODE0_CTRL_MATCHCLR |
   RTC_MODE0_CTRL_PRESCALER_DIV256;
while(RTC->MODE0.STATUS.bit.SYNCBUSY);

RTC->MODE0.COMP[0].reg =1000; //1 s
while(RTC->MODE0.STATUS.bit.SYNCBUSY);

RTC->MODE0.READREQ.reg |= RTC_READREQ_RCONT;
while(RTC->MODE0.STATUS.bit.SYNCBUSY);

RTC->MODE0.CTRL.reg |= RTC_MODE0_CTRL_ENABLE;

RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0;

NVIC_EnableIRQ(RTC_IRQn);
}


So far my focntions look right?
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Generic Clock sam d
« Reply #10 on: September 19, 2016, 06:01:24 pm »
So far my focntions look right?
No, they do not. You have never initialized GCLK[1], so you can't use GCLK_CLKCTRL_GEN(1). Replace it with GCLK_CLKCTRL_GEN(0).

In this case you are not setting prescaler value in the GCLK, but in the peripheral itself. Your peripheral still must be clocked from 8 MHz.
Alex
 

Offline losstTopic starter

  • Contributor
  • Posts: 21
  • Country: dz
Re: Generic Clock sam d
« Reply #11 on: September 19, 2016, 06:11:42 pm »
I must use this:
Code: [Select]
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN(0) |
GCLK_CLKCTRL_CLKEN |
GCLK_CLKCTRL_ID(RTC_GCLK_ID);

    GCLK->GENDIV.reg = GCLK_GENDIV_DIV(7); // the clock source divided by 2^(GenDIV.DIV+1)

    GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(0) |
GCLK_GENCTRL_DIVSEL;

What is the interest of
Code: [Select]
RTC_MODE0_CTRL_PRESCALER_DIV256;   ?
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Generic Clock sam d
« Reply #12 on: September 19, 2016, 06:17:13 pm »
I must use this:
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN(0) | ...
You can't use 0 in this case, because 0 is attached to 8 MHz source. If you want to do prescaling with GCLK, then you need to pick another GCLK.

       GCLK->GENDIV.reg = GCLK_GENDIV_DIV(7);      // the clock source divided by 2^(GenDIV.DIV+1)
Here you also need to specify the GCLK ID, which you want to divide.

   
       GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(0) |   GCLK_GENCTRL_DIVSEL;
Again, you can't use 0 here. You also need to enable it (GCLK_GENCTRL_GENEN).

What is the interest of
Code: [Select]
RTC_MODE0_CTRL_PRESCALER_DIV256;   ?
That is additional divider, giving you more flexibility. If the range of this divider is enough to get the required resulting frequency, then just use this.

Just change GCLK_CLKCTRL_GEN(1) to GCLK_CLKCTRL_GEN(0) in your original code.
« Last Edit: September 19, 2016, 06:18:48 pm by ataradov »
Alex
 

Offline losstTopic starter

  • Contributor
  • Posts: 21
  • Country: dz
Re: Generic Clock sam d
« Reply #13 on: September 19, 2016, 06:25:08 pm »
I use this function but it's not correct I don't have the clock:
Code: [Select]
void Initialization_RTC(void)
{
GCLK->CTRL.reg = GCLK_CTRL_SWRST;
while (RTC->MODE0.CTRL.bit.SWRST);
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}

GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN(1) |
GCLK_CLKCTRL_CLKEN |
GCLK_CLKCTRL_ID(RTC_GCLK_ID);


GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(8) |
                                            GCLK_GENDIV_ID(1));

    GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |
GCLK_GENCTRL_ID(1)|
GCLK_GENCTRL_DIVSEL);

while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}


RTC->MODE0.CTRL.reg = RTC_MODE0_CTRL_MODE_COUNT32;
while(RTC->MODE0.STATUS.bit.SYNCBUSY);

RTC->MODE0.CTRL.reg |= RTC_MODE0_CTRL_MATCHCLR |
   RTC_MODE0_CTRL_PRESCALER_DIV256;
while(RTC->MODE0.STATUS.bit.SYNCBUSY);

RTC->MODE0.COMP[0].reg =1000;
while(RTC->MODE0.STATUS.bit.SYNCBUSY);

RTC->MODE0.READREQ.reg |= RTC_READREQ_RCONT;
while(RTC->MODE0.STATUS.bit.SYNCBUSY);

RTC->MODE0.CTRL.reg |= RTC_MODE0_CTRL_ENABLE;

RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0;

NVIC_EnableIRQ(RTC_IRQn);

}

Now I do not know what is the frequency of the clock source
« Last Edit: September 19, 2016, 06:27:27 pm by losst »
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Generic Clock sam d
« Reply #14 on: September 19, 2016, 08:26:03 pm »
Now I do not know what is the frequency of the clock source
You are attaching a peripheral to a clock source and after that you are configuring that clock source.

And even reset of the peripheral should happen after you configured all the clocks.

Also, now you have both dividers enabled, so your final clock will be 8 MHz / (256 * 256).

Also, how do you know that your clock is not correct? I have not checked that RTC code, I really don't know if it works. Start with my TC code that is known to be correct, and experiment with its clocking.

Why do you want that RTC in a first place? It is a special and weird timer,  for time keeping. Just use a normal TC.
Alex
 

Offline losstTopic starter

  • Contributor
  • Posts: 21
  • Country: dz
Re: Generic Clock sam d
« Reply #15 on: September 19, 2016, 08:32:13 pm »
Sorry but I do not understand where I realize that:
Quote
you have both dividers enabled, so your final clock will be 8 MHz / (256 * 256).
and
Quote
You are attaching a peripheral to a clock source
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: Generic Clock sam d
« Reply #16 on: September 19, 2016, 08:43:08 pm »
Sorry but I do not understand where I realize that:
Quote
you have both dividers enabled, so your final clock will be 8 MHz / (256 * 256).
GCLK_GENDIV_DIV(8) and RTC_MODE0_CTRL_PRESCALER_DIV256.

and
Quote
You are attaching a peripheral to a clock source

GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN(1) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID(RTC_GCLK_ID);   

And again, start any experiments with clocks from a known functioning peripheral (normal TC in my example). This way you know that if you have a problem, then it is with clock source, not with your peripheral code.
Alex
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf