1

I'm trying to configure the RTC in count mode in the SAM L21 Xplained Pro B with the ultra low power clock OSCULP32K, usign ASF. In order to test it, I followed the Quick start RTC count polled example, which toggles LED0 every 2000 ms by comparing the RTC count with a given period.

In the example, RTC_CLOCK_SOURCE uses RTC_CLOCK_SELECTION_ULP1K. When I change it to RTC_CLOCK_SELECTION_ULP32K, the LED toggles 24 times every 2000ms instead of once every 2000 ms.

I have the following configuration at conf_rtc.h:

#  define RTC_CLOCK_SOURCE    RTC_CLOCK_SELECTION_ULP32K

Then, in conf_clocks.h I configured the main CPU clock at 4Mhz.

/* SYSTEM_CLOCK_SOURCE_OSC16M configuration - Internal 16MHz oscillator */
#  define CONF_CLOCK_OSC16M_FREQ_SEL              SYSTEM_OSC16M_4M
#  define CONF_CLOCK_OSC16M_ON_DEMAND             true
#  define CONF_CLOCK_OSC16M_RUN_IN_STANDBY        false

/* Configure GCLK generator 0 (Main Clock) */
#  define CONF_CLOCK_GCLK_0_ENABLE                true
#  define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY        false
#  define CONF_CLOCK_GCLK_0_CLOCK_SOURCE          SYSTEM_CLOCK_SOURCE_OSC16M
#  define CONF_CLOCK_GCLK_0_PRESCALER             1
#  define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE         false

And in main.c, I configure and initialize the rtc as follows:

/* RTC configuration*/
void configure_rtc_count(void);
struct rtc_module rtc_instance;

// [initiate rtc]
void configure_rtc_count(void)
{
    //! [set_conf]
    struct rtc_count_config config_rtc_count;
    //! [set_conf]

    //! [get_default]
    rtc_count_get_config_defaults(&config_rtc_count);
    //! [get_default]

    //! [set_config]
    config_rtc_count.prescaler           = RTC_COUNT_PRESCALER_DIV_1;
    config_rtc_count.mode                = RTC_COUNT_MODE_16BIT;
    #ifdef FEATURE_RTC_CONTINUOUSLY_UPDATED
    config_rtc_count.continuously_update = true;
    #endif
    config_rtc_count.compare_values[0]   = 1000;
    //! [set_config]
    //! [init_rtc]
    rtc_count_init(&rtc_instance, RTC, &config_rtc_count);
    //! [init_rtc]

    //! [enable]
    rtc_count_enable(&rtc_instance);
    //! [enable]
}
// [initiate rtc]
/* End RTC configuration*/

One it's initialized, the code at main(void) reads:

int main (void)
{
    system_init();
    configure_rtc_count();

    /*test RTC - toggle LED0 each 2000 ms*/
    rtc_count_set_period(&rtc_instance, 2000);

    for (;;)
    {
        /*test RTC - if count match, toggle LED0 each 2000 ms*/
        if (rtc_count_is_compare_match(&rtc_instance, RTC_COUNT_COMPARE_0)) 
        {
            /* Do something on RTC count match here */
            port_pin_toggle_output_level(LED_0_PIN);

            rtc_count_clear_compare_match(&rtc_instance, RTC_COUNT_COMPARE_0);
        }
        /*end test RTC*/
    }
}

I cannot find the explanation of what is the meaning of config_rtc_count.compare_values[0] = 1000; I changed it to 32000, but the LED doesn't blink, and if I lower it under 1000, it keeps the same toggle rate...What does this mean?

In the examples like http://www.atmel.com/Images/Atmel-42471-SAM-L21-ADC-Sampling-using-Low-Power-Features_ApplicationNote_AT12705.pdf it seems the RTC is configured only with the #define RTC_CLOCK_SOURCE at conf_rtc.h.

However in others like http://www.atmel.com/Images/Atmel-42111-SAM-RTC-Count-Driver-RTC-Count_ApplicationNote_AT03249.pdf it defines GLCK 2 as:

/* Configure GCLK generator 2 (RTC) */
# define CONF_CLOCK_GCLK_2_ENABLE true
# define CONF_CLOCK_GCLK_2_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_2_CLOCK_SOURCE    SYSTEM_CLOCK_SOURCE_OSC32K
# define CONF_CLOCK_GCLK_2_PRESCALER 32
# define CONF_CLOCK_GCLK_2_OUTPUT_ENABLE false

Does anyone know how to configure the RTC with the ULP32k keeping the correct count rate?

Alvaro Muro
  • 57
  • 2
  • 11
  • Is it irrelevant what the frequency of your main clock is? RTCs are usually driven off the 32768Hz clock/crystal. – Ed King Nov 02 '17 at 09:39
  • As far as I understood, the main clock source is configured as the internal 16M oscillator preescaled at 4Mhz, while the RTC clock source should be the internal ULP32K oscillator. They are two separate clock sources, but I don't know if the main clock interferes with the rtc clock frecuency... – Alvaro Muro Nov 02 '17 at 13:27
  • Please add your configuration for GCLK generator 2 (RTC) to the code. It's not clear what your RTC is being clocked from. – Ed King Nov 02 '17 at 14:53
  • I have edited my question adding more info on GLCK2. Is it always directly connected to RTC? – Alvaro Muro Nov 03 '17 at 08:02
  • Assuming you have enough configuration code to enable the 32kHz oscillator (I can't see definitive code in Atmel's stuff), it seems GLCK2 is the peripheral clock for the RTC. It's not clear to me from the ASF documentation what the difference between `set_period()` and `set_count()` are, but if you've got the clocks configured correctly then your code matches their example and it should toggle the LED every 2s. I would get it to that point first, then change the count and period individually to see what they actually do before changing the clock source. – Ed King Nov 03 '17 at 10:21
  • I got it toggling every 2s, with the ULP1Khz, without defining GLCK2. Changing the period results in a change of toggling period. The compare_values[0] = 1000; is a kind of resolution, if it's lower than the period, the LED toggles. If it's higher (e.g. 2001, with a period of 2000) the comparison is never true, so the LED won't toggle. I changed the clock source to ULP32k and prescaler, but it keeps toggling too fast. Maybe the set_period function needs 1kHz clock source... Anyway, I decided to use the RTC calendar mode, which works great for my application. Many thanks for your kind advice. – Alvaro Muro Nov 06 '17 at 09:41
  • No worries. I'd recommend answering your own question with what you've found, it may help others. – Ed King Nov 06 '17 at 10:11

1 Answers1

0

Thanks to the suggestions of Ed King, here go the current findings on this matter:

The Quick Start for the SAM RTC Count Driver (Polled)(ATSAML21J18A), from Atmel Studio 7, toggles LED0 every 2000ms, using rtc_count_is_compare_match(&rtc_instance, RTC_COUNT_COMPARE_0).

In order for this to work at the right period of 2000ms, and if you want to use the Ultra Low Power Clock source, the RTC clock source must be defined at conf_rtc.h as:

#  define RTC_CLOCK_SOURCE    RTC_CLOCK_SELECTION_ULP1K 

The prescaler must be RTC_COUNT_PRESCALER_DIV_1; (see configuration in the question)

There is no need of defining GLCK2 at conf_clocks.h.

The compare_values[0] = 1000; seems to be a kind of resolution counter, if it's lower than the selected toggle period, the LED toggles. If it's higher (e.g. 2001, with a period of 2000) the comparison seems it's never true, so the LED won't toggle. In any case, it doesn't change the toggling frequency.

Changing the value in rtc_count_set_period(&rtc_instance, 2000); results in a change of toggling period.

The OSCULP32k oscillator has two modes, one at 32kHz and another at 1kHz. I wanted to use the clock source at 32kHz in this example, so I changed

# define RTC_CLOCK_SOURCE RTC_CLOCK_SELECTION_ULP32K

and experimented with the different prescalers, but the LED kept toggling too fast. I assume this happens because the set_period function needs 1kHz clock source to work in ms, although more clear explanations could be useful here.

As a conclusion, the purpose of using the OSCULP32k is to reduce energy consumption, so I guess that the objective is fullfilled using both ULP32k and ULP1k modes.

Alvaro Muro
  • 57
  • 2
  • 11