Sporadic reset problems on dsPIC30F6014

General discussion on mikroPascal for dsPIC30/33 and PIC24.
Post Reply
Author
Message
sofer
Posts: 5
Joined: 24 Oct 2006 15:04

Sporadic reset problems on dsPIC30F6014

#1 Post by sofer » 24 Oct 2006 15:11

Hi,

We have quite a complex code that does a lot of things. It suffers from sporadic reset problems, especially while doing RS-232 communications.
We think it might be related to stack overflows.
The questions are as follows:
1. How can we see the stack status ?
2. It is possible to enlarge the stack or make it deeper ?

If anyone encounter similar reset problems on this chip before and has any helpfull comments, any info will be appreciated

Thanks.

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

Re: Sporadic reset problems on dsPIC30F6014

#2 Post by zristic » 24 Oct 2006 15:38

You can try to make a trap and to catch why the chip resets. See the example "c:\program files\Mikroelektronika\mikroPascal dsPIC\Examples\Dsp\P30F4013\Signal Generator\" which shows how to catch traps.

The first step would be to identify why it resets (can be a divison by zero for example). The next step would be to find at which address it resets (it will help you find an ofending source code line). In order to find at which address it resets use this assembly:

Code: Select all

// math trap:
procedure MathErrorTrap; org $12; // div by zero etc.
begin
  LATB := $A0A0; // signalize math trap
 // write last known program address to PORTD (last program address before jumping here)
    asm
      MOV [w15-32], w13
      MOV w13, LATD
    end;
  while true do // stop here
    nop;
end;

// wrong address trap
procedure AddressTrap(); org 0x08;   
  begin
    LATB := 0xAAAA; // signalize address trap
   // write last known program address to PORTD
    asm
      MOV [w15-32], w13
      MOV w13, LATD
    end;
    while true do nop; // stay here
  end;
Note: Program address is 24 bits. [w15-32] contains lower 16 bits of the address, while [w15-34] contains upper 8 bits.

Next version of mikroPascal for dsPIC will (hopefully) come out with ICD, so debugging this kind of problems will be much easier.

LGR
Posts: 3204
Joined: 23 Sep 2004 20:07

#3 Post by LGR » 24 Oct 2006 16:08

Speaking of dsPIC and stack, is there yet a way to adjust the stack RAM allocation? I recall that in earlier versions, it was fixed at 50%, and couldn't be adjusted.
If you know what you're doing, you're not learning anything.

sofer
Posts: 5
Joined: 24 Oct 2006 15:04

#4 Post by sofer » 24 Oct 2006 19:23

Zristic Hi,

Thanks for your informatice reply.
How do you know that the address is stored at [w15-32] and [w15-34] ? Where is this documented ?

I am asking because I tried and I get an address trap at address 0. It is not very useful for determining where my problem is. So, I am probably doing something wrong.

Reset usually happens during attempts to communicate with the dsPIC over the UART. It happens only 1 in 10 or 20 attempts and it is completely random. Thus, I gathered that probably some other interrupt or event occurs during attempt to communicate and the occurence of the two events simultanously is a rare one.

Do you have any helpfull insight ?

Thanks.

Skyline
Posts: 267
Joined: 10 Jan 2006 09:35

#5 Post by Skyline » 25 Oct 2006 08:59

Hi,

I use the 30F4013 and 30F6014A with mikroBasic for dsPIC. I note that you are using mikroPascal.

I too have encountered similar sporadic resets in a program that uses multiple interrupts - UART interrupts, port interrupts and multiple timer interrupts for RTC, ICs and OCs/PWMs. Maybe my experience would be useful for you.

A. Problem
In trying to trace the bug I managed to get the resets to occur "consistently" instead of sporadically, and narrowed the problem to two interrupts occuring simultaneously. This is also your surmise. In my case, it was two timer interrupt routines, and by varying the period register of one of the output capture timers, I can control the interval before the two timer interrupts coincide causing a reset, hence confirming the problem of the simultaneous interrupts.

B. Silicon Bug
Looking at the Microchip errata for the 4013 and 6014:
Module: Interrupt Controller – Sequential Interrupts

When interrupt nesting is enabled (or NSTDIS (INTCON1<15>) bit is '0'), the following sequence of events will lead to an Address Error trap. The
generic terms “Interrupt 1" and “Interrupt 2" are used to represent any two enabled dsPIC30F interrupts.
1. Interrupt 1 processing begins
2. Interrupt 1 is negated by user software by one of the following methods:
- CPU IPL is raised to Interrupt 1 IPL level or higher or
- Interrupt 1 IPL is lowered to CPU IPL level or lower or
- Interrupt 1 is disabled (Interrupt 1 IE bit set to 0) or
- Interrupt 1 flag is cleared
3. Interrupt 2 with priority higher than Interrupt 1 occurs.
So it seems that in my case, if I clear the interrupt flag in the first interrupt routine and a higher priority interrupt occurs, a trap would be generated and since traps aren't trapped by my program the dsPIC resets.

C. Workarounds
#1. I put all interrupts on same priority, but resets still happen;

#2. I put "disi" at the top of every interrupt routine as per errata recommendation, resets still happen;

Code: Select all

 asm
  disi #2
  end asm
#3. I disabled all nested interrupts as per errata recommendation - problem solved.

Code: Select all

main:
    nstdis = 1
#4. Use the 6014A silicon instead of the 6014.
I use the original 4013 code without workarounds on a 6014A - seems to work, no resets occur.

D. Solution
I believe workaround #1 and #2 can work - didn't spend time to understand why #1 and #2 didn't work for me.
Work around #3 is my current solution - the dsPIC can now run for weeks with all fireworks firing. Disabling nested interrupts has no impact for my code because my interrupt routines are short, so a higher priority interrupt can afford to wait 2us max for the lower priority interrupt to finish.
Workaround #4 - I use the original code without any of the workarounds on a 6014A and the sporadic resets didn't occur. Not fully tested though because my development bed is 4013 and I simply move tested 4013 codes (with the nstdis =1) to the 6014A.

E. Suggestions
If your problem is similar to mine, disabling nested interrupts nstdis = 1 is the easiest, however looking at the silicon errata for 6014 you may prefer to move to a 6014A.
If your problem still occur, you may want to post some code here for us to experiment. You may also want to make use of the 4-byte fifo buffer of the UART to reduce the interrupt latency requirement. Or even run the UART without interrupts by polling the UART flag in the mainline code and making use of the UART fifo buffer.

As for enlarging the stack, go to Edit Project, under Memory Usage there is a slider for Dynamic Link / Static Link, I assume the slider lets you allocate memory for dynamic memory including stack memory. However, on the 6014, ram is 8kB, and the default 50% 4kB for dynamic memory seems plentiful for stack, unless your routines uses a lot of local memory / data.

sofer
Posts: 5
Joined: 24 Oct 2006 15:04

#6 Post by sofer » 25 Oct 2006 09:49

Skyline Hi,

Thanks for all your helpful comments.
Unfortunately, workaround #3 doesn't do it for me.
We do plan to move to 6014A soon (new board is on the way), but in the meantime I have to live with the current hardware.

The fact that the chip is performing reset is problematic for me because when it resets it reprograms some RF synthesizers which should remain locked. What I thought is using the address error trap to set some flag so that I might not reprogram the synthesizers if a trap occured. The problem is that I haven't figured how to cause the trap to terminate (if at all possible).
What flag do I need to clear so that a trap will terminate and normal program execution will resume ?
Since the trap is a hard trap and reset is already performed, will the program start from the beginning after leaving the trap ?

Thanks.

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

#7 Post by zristic » 25 Oct 2006 10:10

sofer wrote:How do you know that the address is stored at [w15-32] and [w15-34] ?
:roll: Well, I worked on it for almost two years.
Where is this documented ?
There is a free online book about dsPIC which is getting prepared. It is supposed to get released this year. It will have a description of memory usage for all mE compilers for dsPIC, along with useful examples for DSP.

Capturing traps is pretty simple, once you get it work it will became a powerful tool. Just follow what is done in the mentioned examples and it will work fine.

@skyline: thanks for that important information.

sofer
Posts: 5
Joined: 24 Oct 2006 15:04

#8 Post by sofer » 25 Oct 2006 10:18

Zristic Hi,

I didn't mean to sound critical of your knowledge. I am sure you are working with this material much longer than I am. I just wanted to double check because I couldn't get it to work.
Can you help me with the other info I asked Skyline ? Can you exit a trap and resume graceful program execution ? If so how to do it ?

Thanks.

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

#9 Post by zristic » 25 Oct 2006 10:34

sofer wrote:Can you exit a trap and resume graceful program execution?
You should consider a trap just like any other procedure. If something wrong occurs, the program will jump to that procedure, execute it and continue where it stopped previously.

All you have to do is to write an apropriate trap handler inside the compiler and you will be fine. The example above shows how to write a math trap and stack overflow trap. The implementation in a trap procedure is not really important, you can just place a nop there. Just make sure you wrote a trap procedure in your program, otherwise dsPIC will keep on reseting.

However, it would be wise that you discover why the chip resets, simple catching of the trap is not solving the problem.

sofer
Posts: 5
Joined: 24 Oct 2006 15:04

#10 Post by sofer » 25 Oct 2006 10:45

I totally agree that simply catching the trap doesn't solve the problem, but unfortunately I need a quick and dirty solution for now in order to have the time to solve the problem later.
My problem is that I write a simple address error trap that contains only one line: setting a variable, but the processor gets stuck in it forever, so I thought I should clear some flag or something so that it will let me exit. If I don't define the address error trap the process just resets and continues normally so what am I doing wrong with the error trap ?

Thanks.

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

#11 Post by zristic » 25 Oct 2006 10:52

In that case you will have to see what caused the trap by extracting origin address of the problematic line. Use [w15-32] to find out what program address is failing. Then use ASM view to find the address and finally, to decode line of code which corresponds to that address.

Skyline
Posts: 267
Joined: 10 Jan 2006 09:35

#12 Post by Skyline » 25 Oct 2006 12:17

Hi,

Noted that #3 didn't work. By the way, for completeness I should have wrote (mB for dsPIC):

Code: Select all

symbol NSTDIS = Intcon1.15
main:
nstdis = 1     'reset default is nstdis = 0 nested interrupts enabled
Have not done traps before, but for address error trap routine the 30F Family Reference Manual 70046E says :
An address error can be detected in software by polling the ADDRERR status bit (INTCON1<3>).
To avoid re-entering the Trap Service Routine, the ADDRERR status flag must be cleared in
software prior to returning from the trap with a RETFIE instruction.
So you may need to clear this bit in your address error trap routine to prevent being stuck in the trap routine.

The next problem is where the address trap routine returns to in the program. Depending on the problem causing the address trap, after you clear the address error status flag, the PC may contain a valid instruction and your program continues normally. If however the PC contains an invalid PC, that the address trap will trap again. In this case, you may need to add to the last lines of the trap routine :

Code: Select all

asm
 goto _main
end asm
and jump to the beginning of your program code.

So, in the address trap routine :
clear the ADDRERR bit,
set you own flag,
jump to _main,

in your main routine :
test your flag to skip RF init.

Er ... the above verbage untested!

Also, if you suspect the UART routines are causing the traps, you may want to relook whether the array indices do go out of bounds.

JimKueneman
Posts: 417
Joined: 10 Jan 2009 22:03

Re: Sporadic reset problems on dsPIC30F6014

#13 Post by JimKueneman » 30 Apr 2011 19:15

Are these off sets still valid in the new 4.80 compiler?
// math trap:
procedure MathErrorTrap; org $12; // div by zero etc.
begin
LATB := $A0A0; // signalize math trap
// write last known program address to PORTD (last program address before jumping here)
asm
MOV [w15-32], w13
MOV w13, LATD
end;
while true do // stop here
nop;
end;

// wrong address trap
procedure AddressTrap(); org 0x08;
begin
LATB := 0xAAAA; // signalize address trap
// write last known program address to PORTD
asm
MOV [w15-32], w13
MOV w13, LATD
end;
while true do nop; // stay here
end;
Jim

Post Reply

Return to “mikroPascal for dsPIC30/33 and PIC24 General”