SAMD20J17 - Watchdog callbacks/application note

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Everyone,

 

I'm using AS7.x and am trying to use the WDT module. I am also following the application note for using the watchdog in a callback configuration:

http://www.atmel.com/Images/Atmel-42124-SAM-Watchdog-WDT-Driver_ApplicationNote_AT03264.pdf

 

When I put the watchdog code in to my application, it appears to hang here (in wdt.c) for-ever which truly is ironic.

 

       while (wdt_is_syncing()) {

              /* Wait for all hardware modules to complete synchronization */

       }

 

 

void configure_wdt(void) {

  struct wdt_conf config_wdt;

  wdt_get_config_defaults(&config_wdt);

  config_wdt.always_on = false;

  config_wdt.clock_source = GCLK_GENERATOR_4;

  config_wdt.timeout_period = WDT_PERIOD_4096CLK;

  config_wdt.early_warning_period = WDT_PERIOD_2048CLK;

  wdt_set_config(&config_wdt);

}

 

void configure_wdt_callbacks(void)

{

  wdt_register_callback(watchdog_early_warning_callback, WDT_CALLBACK_EARLY_WARNING);

  wdt_enable_callback(WDT_CALLBACK_EARLY_WARNING);

}

 

void watchdog_early_warning_callback(void)

{

}

 

int main(void) {

  system_init();

 

  configure_wdt(); // gets stuck here

  configure_wdt_callbacks();

  ...

 

 

 

Any ideas on making this work? :-)

 

Thanks

Last Edited: Wed. Jul 25, 2018 - 09:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

  configure_wdt(); // gets stuck here

Surely you can follow it "into" this call and find out where in that it is actually "stuck"? Presumably there's a wait loop on some status bit that is never set or something?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It appears as though the STATUS.reg register is not getting the appropriate bit cleared and always returning true.

 

 

#define WDT_STATUS_SYNCBUSY (0x1ul << WDT_STATUS_SYNCBUSY_Pos)

 

* \retval false If the module has completed synchronization

* \retval true If the module synchronization is ongoing

static inline bool wdt_is_syncing(void)

{

  Wdt *const WDT_module = WDT;

  #if (SAML21) || (SAML22) || (SAMC20) || (SAMC21)

  if (WDT_module->SYNCBUSY.reg) {

  #else

    if (WDT_module->STATUS.reg & WDT_STATUS_SYNCBUSY) { // right here

  #endif

      return true;

    }

    return false;

}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have the watchdog working;

 

I changed

...

     config_wdt.clock_source = GCLK_GENERATOR_2; // from _4

...

 

Why didn't config_wdt.clock_source = GCLK_GENERATOR_4 work?
 

Last Edited: Thu. May 19, 2016 - 09:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey all, 

 

Sorry to revive a dead post, but I thought I would add some things that I looked into and helped out with me understand some things.

 

Preface this with I’m using AS7.X, ASF(3.40.0) with a SAMD21. I know the OP is using SAMD20J17 and possibly ASF(v4?), so not sure how much it would directly correlate.

 

Also, here is some good clock reading: http://www.lucadavidian.com/2017/08/08/arduino-m0-pro-il-sistema-di-clock/

 

I’ve looked further into this and have followed the function calls into ASF land trying to figure out where GCLKs are setup:

 

  • system_init() is called from main.c and goes to system.c
  • Calls system_clock_init() and goes to clocks.c
    • This is the very modular clock initialization based on what the user has defined in conf_clocks.h
  • Calls system_gclk_init() and goes to gclk.c
    • This just initializes the GCLK driver and not the individual generic clocks. Turns on the digital interface clock to the module and software resets it.
  • Returns to clocks.c and initializes all GCLKs via _CONF_CLOCK_GCLK_CONFIG based on what is selected in conf_clocks.h

 

Via Clocks.c

#  define _CONF_CLOCK_GCLK_CONFIG(n, unused) \

    if (CONF_CLOCK_GCLK_##n##_ENABLE == true) { \

    struct system_gclk_gen_config gclk_conf;                          \

    system_gclk_gen_get_config_defaults(&gclk_conf);                  \

    gclk_conf.source_clock    = CONF_CLOCK_GCLK_##n##_CLOCK_SOURCE;   \

    gclk_conf.division_factor = CONF_CLOCK_GCLK_##n##_PRESCALER;      \

    gclk_conf.run_in_standby  = CONF_CLOCK_GCLK_##n##_RUN_IN_STANDBY; \

    gclk_conf.output_enable   = CONF_CLOCK_GCLK_##n##_OUTPUT_ENABLE;  \

    system_gclk_gen_set_config(GCLK_GENERATOR_##n, &gclk_conf);       \

    system_gclk_gen_enable(GCLK_GENERATOR_##n);                       \

}

 

My original assumption was that ASF would setup the all clocks for the WDT when added via ASF wizard and when using the library functions. This seems to be 50/50 correct. When using the library files(and the Example here), it sets up the digital interface clock but the WDT still needs a source clock which is one of the GCLKs. These clocks need to be enabled in conf_clocks.h. It seems that on a fresh ASF project, only GCLK[0] is enabled by default which is the main clock(also the CPU clock?). So this would probably explain why GCLK_GENERATOR_4 would not work. It’s trying to setup on a non-enabled clock and it is hanging waiting for something that won’t sync.

 

Now the issue is that changing GCLK_GENERATOR_4 to GCLK_GENERATOR_2 works. However, when I look at my conf_clocks.h none of my GCLKs(Other than GCLK[0]) are enabled.

 

Why does this work??

Last Edited: Wed. Jul 25, 2018 - 09:32 PM