Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Random Watch dog reset.

Status
Not open for further replies.

ArvindEdaB

Newbie level 4
Joined
Oct 11, 2018
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
96
Hi,

I am currently using PIC12F/LF1822 MCU,

for which I have generated USART and WDGT code using MPLAB MCC code generator, And they are working fine...

But I have a situation here as follows,

I have a requirement of receiving 19 bytes of frame over USART. Once received 19 Bytes are passed to a handler for further processing.

Info: USART is ISR based.

I have started sending the Data byte by byte over USART using Hercules tool on my laptop.

I am facing a WDGT reset on random upon the reception characters.

The following is the USART Rx ISR code for better understanding:),



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#define EUSART_RX_BUFFER_SIZE 19
 
volatile uint8_t eusartRxHead = 0;
volatile uint8_t eusartRxBuffer[EUSART_RX_BUFFER_SIZE];
volatile uint8_t eusartRxCount;
 
void EUSART_Receive_ISR(void)
{
    volatile uint8_t u8Char;
 
    if(1 == RCSTAbits.OERR)
    {
        // EUSART error - restart
 
        RCSTAbits.CREN = 0;
        RCSTAbits.CREN = 1;
    }
   
    u8Char = RCREG;
    CLRWDT();  /*This line of Code added by me*/
    eusartRxBuffer[eusartRxHead++] = u8Char;
 
   /*sizeof(eusartRxBuffer) is 19 bytes*/
    if(sizeof(eusartRxBuffer) <= eusartRxHead)
    {
        eusartRxHead = 0;
        EUSART_Write('D');      /*This line of Code added by me*/
        EUSART_DecodePadding(eusartRxBuffer);     /*This line of Code added by me*/
        EUSART_Write('E');      /*This line of Code added by me*/
    }
    else
    {
        EUSART_Write('G');     /*This line of Code added by me*/
    }
    EUSART_Write('O');     /*This line of Code added by me*/
    eusartRxCount++;
}




I have tried Clearing the Watchdog in USART ISR as mentioned bove in the code.
I have tried increasing the Watchdog expiry time to 256 seconds (i.e.., WDTCON = 0x12)

Still the issue persists...

Strange observations,

I have observed some strange things while transmitting the data over USART that when WDGT reset happens it seems like it is resetting the MCU immediately not after 256 seconds.

I am sure that its WDGT reset as because if I disable WDGT Init, reset doesn't occur...

I am adding an image for more details,

In the Image,
3 is the character sent from the tool and received the MCU.
GO -> represents the hit of ISR as mentioned in the above code.
DSEO -> represents Data handed over to handler, processed it, came back and exited the ISR. i.e, The task I need has successfully happened

R-> represents a Reset.

Kindly help me...:(


Additional Info if required:

MCC generated Code for USART init.....

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void EUSART_Initialize(void)
{
    // disable interrupts before changing states
    PIE1bits.RCIE = 0;
 
    // ABDOVF no_overflow; SCKP Non-Inverted; BRG16 16bit_generator; WUE disabled; ABDEN disabled; 
    BAUDCON = 0x08;
 
    // SPEN enabled; RX9 8-bit; CREN enabled; ADDEN disabled; SREN disabled; 
    RCSTA = 0x90;
 
    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave; 
    TXSTA = 0x24;
 
    // SP1BRGL 207; 
    SPBRGL = 0xCF;
 
    // SP1BRGH 0; 
    SPBRGH = 0x00;
 
 
    // initializing the driver state
    eusartTxHead = 0;
    eusartTxTail = 0;
    eusartTxBufferRemaining = sizeof(eusartTxBuffer);
 
    eusartRxHead = 0;
    eusartRxTail = 0;
    eusartRxCount = 0;
 
    // enable receive interrupt
    PIE1bits.RCIE = 1;
}

 

Attachments

  • b43ae4b4-e541-4be8-a509-6a1c173cf0f8.jpg
    b43ae4b4-e541-4be8-a509-6a1c173cf0f8.jpg
    84.9 KB · Views: 104
Last edited by a moderator:

Hi,

I have tried increasing the Watchdog expiry time to 256 seconds (i.e.., WDTCON = 0x12)
WDTCON 0x12 = 0b 0001 0010 .
Where the red bits are the bits for the timeout.

--> 01001 which gives 512ms timeout.

To get 256 seconds you need to set the WDTCON to 0x24 = 0b 0010 0100

Klaus

Btw: We don´t see the rest of the code.... but with the given piece of code the watchdog doesn´t make much sense (at least to me) .. because it will repeatedly hard reset the microcontroller when there is no communication. --> I´d use a software timeout for this.
 
Hi KlausST,

Thanks for the info.

Let me try with the option u have provided...

With Regards,
ArvindEdaB.
 

I would remove everything from the ISR except resetting the interrupt bit, capturing the received character to a variable and setting a flag to say something has been received. It is quite likely the amount of processing inside the ISR is causing a serial data overflow and the reset is caused by stack overflow rather than a watchdog reset. Get out of the ISR as quickly as possible and do the data processing in the 'main()' code.

Brian.
 
Firstly the standard quesitons:
- how do you know it is the WDT that is timing out? Are you checking the bits in the STATUS register or what?
- have you turned off the WDT to see if the problem goes away? If it doesn't then the problem is not the WDT.
What is happening in the 'EUSART_Write' and 'EUSART_DecodePadding' functions? I'm guessing that they are in some way blocking (directly or indirectly) and making the run-time of the ISR quite long.
An ISR should run very quickly so that it does not hold up the normal level code. Rather than making those calls in the ISR, I'd set a (volatile) flag that I check in the main loop and generate the output (etc.) there.
Also watch out for calling functions from within an ISR with XC8 - if I remember correctly this can cause the compiler to duplicate the called function so that one is called from the main level code and the other from within the ISR (I've not used XC8 for a long time and I think there are conditions for this to occur that I have probably forgotten).
Susan
 
Hi Aussie,

Thanks for the reply, I have tried removing WDGT init and execute. Apparently everything is working fine.
From Snapshot, If decode padding is executed we have D,E chars Transmitted...Which is not the case for every reset.

" I have tried removing WDGT init and execute " doesn't make me to feel reliable...

I will look into more reliable way than assumption...

Mean while, Kindly try to help me in the same:)

Thanks in advance.

With Regards,
ArvindEdaB
 

Did you follow the suggestions to remove everything from receive ISR that doesn't belong there? Particularly sending multiple UART characters?
 

Hi FvM,

Yes, I have tried removing everything...

But, the reset still happens..

The STATUS register has a status as 0x30...

Currently looking into it...:)

With Regards,
ArvindEdaB.
 

Basically follow this method:

1. configure the interrupts so one occurs when a character is received.
2. In the ISR, check the USART caused the interrupt, save the received character, set a flag to say one is present.
3. exit the ISR.

4. in the main() code, check the flag.
5. if it was set, reset it and process the character.

so no slow tasks or delays or status checking are done inside the ISR. A common reason for 'random' resets is a backlog of interrupt requests waiting to be processed which inevitably results in overruns and missed counts. In extreme circumstances it can result in a stack overflow.

Brian.
 

The STATUS register has a status as 0x30...
Are you sure?
The PIC12(L)F1822 STATUS register has the top 3 bits as 'unused' and they return 0. Therefore the most significant hex digit can only be '1' at most.
Also you must look at more than just the STATUS register to determine the cause of the reset. Check out Section 7.10 of the data sheet and report the various bits on the initial power up and also after the 'watchdog reset'.
Susan
 
Yes, I have tried removing everything...
But, the reset still happens.

If you have already removed all of the overheaded stuffs from the ISR's but the problem persists, how about you show the code in main()? Are you sure there is no long loop there avoiding to update the Wachdog counter in time?
 
Hi Andre,

Thanks for your interest, Actually the problem is solved....

The Actual problem is not not Watch dog.... Its related to stack..

I am not sure why reset haven't happened when I have removed WDGT Init (As I have mentioned in earlier posts)...

I have solved this problem by checking an option "Managed Stack" in the work space settings...

Thanks all... for ur great interest in solving my problem...

With regards,
ArvindEdaB.
 

To be honest, I don't think that this code gonna work. I would not recomend procceed with it. Carefully read what betwixt said.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top