View previous topic :: View next topic |
Author |
Message |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
BSR Error on PIC18F67J50 |
Posted: Mon Apr 28, 2014 2:14 pm |
|
|
Hi found unexpected behavior of Main code due to BSR being corrupted by HIGH INTs.
I.E.
C Code
Code: | if(USB_Status.NewDataToSend) |
Generate the following ASM code
Code: | MOVLB 0x3
BTFSS 0xFB,0x4
BRA 0xFD6E |
That code it's Ok, but since the HIGH INT handler does NOT save the BSR before run the interrupt code What happen if the interrupt stop the Main code after MOVLB 0x3 and before BTFSS 0xFB?
Currently I'm getting BSR =0x09 so when the BTFSS instrucction run reads the wrong RAM address.
So, in order to solve that I disable the HIGH INTs manager and use the following code.
Code: | #INT_RDA2 fast//HIGH
void RX2_ISR(void)
{
char GPS_Dummy;
short RTS_Temp;
#asm
call RX2_ISRL,1
retfie 1
#endasm
RX2_ISRL:
if(FERR2)
{...//interrupt handle
|
Now I check the program address 0x0008 and get this
Code: | MOVLB 0
GOTO RX2_ISR |
Why is that MOVLB 0 there?
I don't need that, It screw up the code because I can't save the BSR!!! _________________ Electric Blue |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Apr 28, 2014 2:35 pm |
|
|
i am not clever enough to understand what
is wrong based on the scant info you post.\
even though i started in assembler with PICS
i do not see the point of the inline assemble in your int handler
and without the ability to assemble what you wrote
can not begin to help you |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Apr 29, 2014 12:44 am |
|
|
Agreed. Data is too little.
The BSR won't get affected by the high interrupts, since these by default will use RETFIE 1, which restores the bank register.
The low priority interrupts add code to do the same.
The assembler is pointless.
Critical question - what compiler version?.
The bank change is there, so the compiler is addressing the bank in which it'd normally save the key registers. Since you are using 'fast' it doesn't, but the bank change required by the handler is left there so you can save the registers. Doesn't matter since the retfie restored the bank.
Obvious things that would/might cause your problem:
1) Interrupt code without saving registers.
2) Two 'fast' interrupts - must never be done - in the manual.
3) A 'fast' and a 'high' interrupt. Not said in the manual, but most compilers will complain.
4) Possibility of a compiler problem, hence _version number_. |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Tue Apr 29, 2014 6:42 am |
|
|
Thanks for answer, the original code for that interrupt is
Code: | #INT_RDA2 HIGH
void RX2_ISR(void)
{
char GPS_Dummy;
short RTS_Temp;
if(FERR2)
{...//interrupt handle
|
I changed from HIGH to FAST because I didn't notice about RETFIE 1.
Anyway, the BSR bug is real I put a break point after
Code: | if(USB_Status.NewDataToSend) |
And time to time, no constantly get BSR = 0x9 instead of BSR = 0x3 and since the generated ASM code for that IF is
Code: | MOVLB 0x3
BTFSS 0xFB,0x4
BRA 0xFD6E |
Theres no other way that something is going wrong on some INT handler.
My actual CCS version is 4.114
Currently I'm using
#INT_TBE
#INT_RDA
#INT_RDA2 HIGH
#INT_CCP2
#INT_CCP1
#INT_AD
And in low power mode
#INT_TIMER1 _________________ Electric Blue |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Apr 29, 2014 7:38 am |
|
|
4.114, is old. About 4 years. It is also in a period where there were some compiler problems. I'd actually be suspicious that it is something like a variable used to hold the bank inside the low priority ISR's getting overwritten. I have a little 'niggle' that there was a thread about this time with a bank select problem. Some careful reading around the end of 2010, might find it.
Some further comments:
Code: |
#INT_RDA2 HIGH
void RX2_ISR(void)
{
char GPS_Dummy;
short RTS_Temp;
if(FERR2)
{...//interrupt handle
|
You don't show enough to be sure, but it looks as if when FERR2 is not true, you don't read the UART. The handler should _always_ read the UART.
Then DEBUG.
Just try disabling individual interrupts one by one, in front of the problem line. Then re-enable them after. You should very quickly be able to find which interrupt causes the problem.
I have to ask why you are using INT_AD?. Are you triggering the ADC with the CCP?. There are only two occasions where INT_AD should be used. The first when it is being used synchronously (triggered by the CCP), and the second when the chip is being put to sleep for the ADC conversion. Otherwise it is 'dis-advisable' to use the interrupt.
Seriously I'd be most suspicious of your compiler version. CCS rarely gets things right on new chips/features when they are first added. and I think your compiler is one of the first to support your chip... |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Tue Apr 29, 2014 2:27 pm |
|
|
Sorry the error handling is like this
Code: | #INT_RDA2 HIGH
void RX2_ISR(void)
{
char GPS_Dummy;
short RTS_Temp;
if(FERR2)
{
GPS_Dummy = fgetc(GPS);
}
GPS_Dummy = fgetc(GPS);
if(OERR2==True)
{CREN2=False;
#asm
nop
nop
#endasm
CREN2=True;
#asm
nop
nop
nop
#endasm
return;
}
if(GPS_RxBufferOffsetI==0 && GPS_Dummy<' ')
{
return;
}
if(LoadConf)
{
GPS_RxBufferOffsetI=0;
return;
}
GPS_WDT=0;
...//interrupt handle |
I'm using INT_AD because I'm using special trigger on CCP every 0.25sec- _________________ Electric Blue |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Apr 29, 2014 2:44 pm |
|
|
Good. A good reason to use INT_AD, and your own error handling.
Have to say though, why bother with the DIY error handling?. Just have ERRORS in the RS232 declaration and CCS will generate the error handling code itself. Re-inventing the wheel?....
Still most suspicious of the compiler version. It really is early for that chip. |
|
|
|