K60 Watchdog Refresh Issue

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K60 Watchdog Refresh Issue

2,596 Views
kashyapgada
Contributor III

Hello

I have a Kinetis K60 100 Mhz controller whose WDOG I want to use. I have pasted the driver for the

watchdog and main code below.

The problem is when the code is running the wdog never refreshes even though i do. when i am debugging

the same code works properly. I have tried adding delay between consecutive refreshes but it just doesnot

work. Please Help.

//////////////////////////////

///////////////////////////////////////////////////////////////////////////////

void main (void)

{

  disable_irq(45) ;

  // Dynamic interrupt vector modification whilst those interruts are disabled

  __VECTOR_RAM[61] = (uint32)uart0_isr;  // plug isr into vector table in case not there already

  /* Enable UART 0 interrupts in NVIC */

  enable_irq(45); //UART IRQ = 45

  motorStatusInit();

// initialize uart rxd txd pins

  PORTB_PCR16 = PORT_PCR_MUX(3);

  PORTB_PCR17 = PORT_PCR_MUX(3);

  uart_init (UART0_BASE_PTR, 100000, 9600);

  UART0_C2 |= UART_C2_RIE_MASK ; // Enable Receive Interrupt

  Init_Gpio();

  Hw_Trig_Test(); //  demo the adc/pdb

  gpio_init(PORTB, PTB, 1, OUTPUT); //Buzzer Output

  wdog_init();

  EnableInterrupts ;

  delay_wdog(100);

  while (1) {

  adc_channel0 = result0A; //12

  finalSendData[5]  = ((adc_channel0 >> 8) & 0x00FF); //toSendData1[1]

  finalSendData[6] =  ((adc_channel0) & 0x00FF); //toSendData2[0]

  adc_channel1 = result1A; //10

  finalSendData[3] = ((adc_channel1 >> 8) & 0x00FF); //toSendData0[1]

  finalSendData[4] = ((adc_channel1) & 0x00FF); //toSendData0[0]

  /* Read Motor Status and update finalSendData with motor status and error bytes */

  delay_wdog(30);

  wdog_refresh();

  delay_wdog(30);

  getAllMotorStatus();

  updateStatusSendData(finalSendData);

  if(Modbus_RxCounter >= Modbus_COMMAND_MAX_LENGTH) {

  crcCheck = receiveData((unsigned char *)Modbus_RxBuffer);

  if (crcCheck == 1) {

  sendData(finalSendData);

  }

  Modbus_RxCounter = 0;

  memset((void *)&Modbus_RxBuffer[0], '\0', sizeof(Modbus_RxBuffer)); //reset array

  }

  }

}

///////////////////////////////////////////////////////////////////////////////

#ifndef  __WDOG_H__

#define  __WDOG_H__

#include <freescale/MK60N512VMD100.h>

#define WDOG_UNLOCK_SEQUENCE_1 0xC520

#define WDOG_UNLOCK_SEQUENCE_2 0xD928

#define WDOG_REFRESH_SEQUENCE_1 0xA602

#define WDOG_REFRESH_SEQUENCE_2 0xB480

void wdog_init(void);

void wdog_refresh(void);

void wdog_enable(void);

void wdog_unlock(void);

void wdog_set_timeout(uint32_t);

void delay_wdog(uint16_t); //Ms second delay required in us

// function prototypes

void wdog_disable(void);

#endif

///////////////////////////////////////////////////////////////////////////////

#include "wdog.h"

#include "common.h"    // Common Kinetis defines

void wdog_init(void){

  wdog_unlock();

  delay_wdog(1);

  WDOG_STCTRLH = WDOG_STCTRLH_DISTESTWDOG_MASK //Disable WDOG Test Mode

  | WDOG_STCTRLH_ALLOWUPDATE_MASK | WDOG_STCTRLH_WDOGEN_MASK | WDOG_STCTRLH_DBGEN_MASK; //Allow WDOG CTRL Ref Update

  WDOG_TOVALH = 0x0000;

  WDOG_WINL = WDOG_WINH = 0;

  WDOG_TOVALL = 0x15ff;

  WDOG_STCTRLH &= ~(WDOG_STCTRLH_ALLOWUPDATE_MASK) ;

}

void wdog_refresh(void) {

  DisableInterrupts;

  WDOG_REFRESH = WDOG_REFRESH_WDOGREFRESH(WDOG_REFRESH_SEQUENCE_1);

  WDOG_REFRESH = WDOG_REFRESH_WDOGREFRESH(WDOG_REFRESH_SEQUENCE_2);

  delay_wdog(100);

  EnableInterrupts;

}

void wdog_enable(void){

  delay_wdog(60);

  wdog_unlock();

  delay_wdog(1);

  WDOG_STCTRLH |= WDOG_STCTRLH_WDOGEN_MASK;

  delay_wdog(20);

}

void wdog_unlock(void)

{

  /* NOTE: DO NOT SINGLE STEP THROUGH THIS FUNCTION!!! */

  /* There are timing requirements for the execution of the unlock. If

   * you single step through the code you will cause the CPU to reset.

   */

  /* This sequence must execute within 20 clock cycles, so disable

         * interrupts will keep the code atomic and ensure the timing.

         */

        DisableInterrupts;

  /* Write 0xC520 to the unlock register */

  WDOG_UNLOCK = 0xC520;

  /* Followed by 0xD928 to complete the unlock */

  WDOG_UNLOCK = 0xD928;

  /* Re-enable interrupts now that we are done */

        EnableInterrupts;

}

void wdog_set_timeout(uint32_t time) {

}

void delay_wdog(uint16_t nCount) {

  uint16_t delay = 0;

  for (delay=0;delay<nCount*10;delay++);

}

void wdog_disable(void)

{

  /* First unlock the watchdog so that we can write to registers */

  wdog_unlock();

  /* Clear the WDOGEN bit to disable the watchdog */

  WDOG_STCTRLH &= ~WDOG_STCTRLH_WDOGEN_MASK;

}

0 Kudos
5 Replies

734 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

I check your void wdog_init(void) function with below code:

WDOG_STCTRLH &= ~(WDOG_STCTRLH_ALLOWUPDATE_MASK) ;

Which will disable further updates to WDOG write once registers.

The unlock sequence is effective only if ALLOWUPDATE is set.

Then after wdog_init, the following unlock sequence is invalid.

Wish it helps.

0 Kudos

734 Views
kashyapgada
Contributor III

Does Refreshing Watchdog require Unlock Sequence? I donot think so.

I commented the line you mentioned but that did not help. The watchdog refreshes properly if i debug in step by step mode but if i just leave it running the watchdog times out.

0 Kudos

734 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

You are right. The [ALLOWUPDATE] bit does not affect the watchdog refresh. Today I do a test based on TWR-K60D100M board with below test code and I could not find the watchdog reset issue happens with checking RCM_SRS0 register. I program the Flash and let it run without debug, if the watchdog reset happen it will light a LED. While, I don't find the led light during the test.

           //unlock the WDOG

      wdog_unlock();

      //enable wdog and use bus clock as counter source

      WDOG_STCTRLH = WDOG_STCTRLH_WDOGEN_MASK | WDOG_STCTRLH_CLKSRC_MASK

                   | WDOG_STCTRLH_ALLOWUPDATE_MASK | WDOG_STCTRLH_IRQRSTEN_MASK;

   

      //set timer overflow time to TIMEOUT_VALUE_BUS

      WDOG_TOVALH = TIMEOUT_VALUE_BUS >> 16;

      WDOG_TOVALL = TIMEOUT_VALUE_BUS;

     

      WDOG_STCTRLH &= ~(WDOG_STCTRLH_ALLOWUPDATE_MASK) ;

     

      while(1)

      {

          WDOG_REFRESH = 0xA602;

          WDOG_REFRESH = 0xB480;

      }

Light led code in sysinit.c

        PORTA_PCR11 |= PORT_PCR_MUX(0x1);

        GPIOA_PDDR |= (0x1 << 11);

        GPIOA_PDOR |= (0x1 << 11);

    

        if ((RCM_SRS0 & RCM_SRS0_WDOG_MASK) == 0x20)

        {

            GPIOA_PTOR |= (0x1 << 11);

        }

Could you test it with your board? And if you could get the same result with me?

0 Kudos

734 Views
kashyapgada
Contributor III

WDOG_STCTRLH_CLKSRC_MASK I had not added to the watchdog init code and from

the example you gave I added i and it worked.

So the problem was with the clock source, i Had previously selected LPO Osc

which i am not sure why did not worked. And Also the alt source selected

now I need to find out what is it.

But Thanks Alot Hui Ma

0 Kudos

734 Views
kashyapgada
Contributor III

Thanks alot I will surely try that inform you the results.

0 Kudos