سؤال

First of all clarify that I'm a newbie in embedded technology. I'm using a NXP LPC1769 board. For some days I've been looking for an example on how to use a watchdog to wake up from deep-sleep mode but I can not find it.

I read chapter 21.1 from UM10360 about Watchdog timer and also 4.8 about power control.

For watchdog I try to wrote this :

void WatchDog_Init(uint32_t TimeOut)
{
  // Set the watchdog timer constant reload value
  LPC_WDT->WDTC =TimeOut * 256 * 4; // timeout value

  // Setup the Watchdog time operating mode in WDMOD register
  LPC_WDT->WDMOD = 0x5; // Watch dog enabled, reset disable , watchdog cleared by software.

  // Enable watchdow by writting 0xAA followed by 0x55 to WDFEED register
  // Reload the watchdog timer with the WDTC value.
  LPC_WDT->WDFEED = 0xAA;
  LPC_WDT->WDFEED = 0x55;

  if ( ! LPC_WDT->WDCLKSEL | ( 1 << 31) )
  {
    // Select internal IRC oscillator to be able to wake up from deep-sleep mode
    LPC_WDT->WDCLKSEL &= ~(0x11);
  }

  NVIC_EnableIRQ(WDT_IRQn);
}

void WDT_IRQHandler(void)
{
  //    //LPC_WDT->WDMOD &= ~WDTOF;     /* clear the time-out interrupt flag */
  //    LPC_WDT->WDMOD |= ( 0 << 2);     /* clear the time-out interrupt flag */

  if ( LPC_WDT->WDMOD & 1 << 2 )
  {
    m_count++;

    // TODO: Wake up CPU!

    // Disable WatchDog Interrupt
    // or the watchdog interrupt request will be generated indefinitely...
    // NOT WORKING :S
    LPC_WDT->WDMOD &= ~(0x4);
    NVIC_DisableIRQ(WDT_IRQn);
  }
}

Although I stop WDT_IRQn board entry in infinite loop.

To set board in deep sleep mode I try to:

// Set device in deep sleep mode....
LPC_SC->PCONP |= 11;     // Enable PM1 and PM0
if ( LPC_SC->PCONP & 0x3 == 0x3)
{
  PRINT_DEBUG("Well!");
}

if ( (LPC_SC->PCONP & ( 1 << ENTER_SLEEP_MODE_CHECK ))>>ENTER_SLEEP_MODE_CHECK)
{
  // Successfully entering to deep-sleep mode
  __WFI;
}
هل كانت مفيدة؟

المحلول

Generally one wouldn't use a watchdog as a wake-up mechanism. You'd instead want to dedicate a general purpose timer (from e.g. chapter 21 of the spec you referenced) for this. The datasheet even mentions that the reason they included "No reset mode":

the intent of the watchdog interrupt is to allow debugging watchdog activity without resetting the device when the watchdog overflows.

So, once you wake up from this, the only option is to disable the interrupt, and at that point you'll never be able to wake with this mechanism again.

But, your ISR code is flawed, as you'll never get into your first conditional. You should change it to:

void WDT_IRQHandler(void)
{
    NVIC_DisableIRQ(WDT_IRQn);
}

Upon the return from this interrupt, the CPU should be awake, and should execute the next instruction after the __WFI; that put it to sleep.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top