CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

INT_RDA2 issue PIC18LF46k80
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
VincentJ



Joined: 21 Oct 2020
Posts: 9

View user's profile Send private message

INT_RDA2 issue PIC18LF46k80
PostPosted: Wed Oct 21, 2020 10:49 am     Reply with quote

Hello,

I have a problem for a few days with UART2 ISR in a PIC18LF46k80 project.

I am using a radio module which sends a 5 bytes message to the PIC as a toggle occurs on a pin.
This message is visible on the oscilloscope so I know that 5 bytes are transmitted whereas only the 2 first bytes are received in the buffer.

Everything is ok with UART1.

I have tried several things to fix this issue and I noticed that if I remove the code of both INT_EXT and INT_EXT1, everything works fine… The 5 bytes are received.
INT_EXT and INT_EXT1 are never triggered.

I need help.
Any idea ?
newguy



Joined: 24 Jun 2004
Posts: 1909

View user's profile Send private message

PostPosted: Wed Oct 21, 2020 11:09 am     Reply with quote

a) Do you have the HIGH option enabled for the external interrupt?

b) Describe the electrical environment. Is there any electrical noise and/or are "heavy current" loads being switched?
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Oct 21, 2020 2:13 pm     Reply with quote

Need to see the code....
Have you set 'ERRORS' option in the USE #RS232(.....commands....) ??
Do you buffer the incoming data ?
VincentJ



Joined: 21 Oct 2020
Posts: 9

View user's profile Send private message

PostPosted: Wed Oct 21, 2020 10:36 pm     Reply with quote

a) The HIGH option is not enabled for the external interrupts

b) The EMC is ok and the external interrupts are not triggered.
The problem continues even if I disable those interrupts.

Parts of the code:
Code:

#use delay(clock=64000000,crystal=16000000,restart_wdt)

#use rs232(UART1, baud=115200, parity=N, bits=8, stream=PORT1, errors)
#use rs232(UART2, baud=115200, parity=N, bits=8, stream=PORT2, errors) 

#INT_TIMER0
void  TIMER0_isr(void)
{                                                                                                         
    //Time out de l'UART2
    if (TO_UART2_ON == 1)
    {
        RDA2_TimeOUT++;
        //Test de dépassement
        if (RDA2_TimeOUT >= 3)  //3: <=> 20ms
        {
            //Données reçues
            //Invalidation de l'interruption RDA2 le temps de copier le buffer temporaire
            disable_interrupts(INT_RDA2);
            //RAZ du compteur de données
            DataCount2 = 0;
            //TimeOut Off
            TO_UART2_ON = 0;
            //RAZ du compteur
            RDA2_TimeOUT = 0;
            //Set du flag de réception d'une trame
            UART2_TrameRecue = 1;
        }
    }
}

#INT_EXT
void  EXT_isr(void)
{
    ...
}                       
             
#INT_EXT1  // interruption des I2C IO EXTENDER
void  EXT1_isr(void)
{
   ...
}               

#INT_RDA2
void  RDA2_isr(void)         
{
    TAB_DataReceived2_Temp[DataCount2]=fgetc(PORT2);
    DataCount2++;
    //RAZ du compteur TimeOut 2
    RDA2_TimeOUT = 0;
    //Valider le timeoutr de l'UART 2
    TO_UART2_ON = 1;
}


(Timer0 is always ON.)
To sum up:
With the code above, only the 2 first bytes of each frame are received.
With the changes below, everything works fine:
Code:

#INT_EXT
void  EXT_isr(void)
{
/*    ...   */
}                       
             
#INT_EXT1  // interruption des I2C IO EXTENDER
void  EXT1_isr(void)
{
/*   ...   */
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 1:14 am     Reply with quote

One thing you say does not make sense. That the problem continues even
if you disable INT_EXT, and INT_EXT1. I would suspect you are not actually
disabling these. Something is enabling them.

Your problem is occurring because you are spending too much time
somewhere in the handler for INT_EXT, or INT_EXT1. Interrupt handlers
need to be quick. If (for example), you had an interrupt handler that
wanted to delay for a time, then you must not do this. Instead you would
have to just set a flag, and perhaps start a timer, then have this interrupt
when the delay is finished and do the rest of your work in the handler
for this.
Now for most interrupts, there would be a potential solution for this,
by making INT_RDA 'HIGH' priority, so that it can be called while the chip
is handling he other interrupt. However in this case this can't be done.
The 'reason', is that if interrupt priorities are used, the INT_EXT interrupt
will always be 'HIGH' priority.
So solutions are:
1) Shorten the time taken in INT_EXT and INT_EXT1. Best solution.
2) Stop using INT_EXT, use INT_EXT1 & INT_EXT2 instead. Then enable
nested interrupts and make INT_RDA2 'HIGH' priority.
3) Also make sure your #USE RS232 setup, has 'ERRORS' enabled. This
should _always_ be done for handlers for hardware UART's, unless you
are adding your own error handling code. Adding this would mean that
though a character (or more) would be lost when the problem happens,
the UART would recover.

Honestly reducing the time code stays in the interrupt handlers is the
'correct' way to fix this.
Repeat the mantra fifty times, 'interrupt handlers should always be quick'....
VincentJ



Joined: 21 Oct 2020
Posts: 9

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 2:06 am     Reply with quote

I am aware of these elements and I stand by what I said.

The problem persists even if RDA2 is the only high priority interrupt.

I had already tried to monitor bits 1 and 2 of RCSTA2 (using #byte RCSTA2 = getenv("sfr:RCSTA2") and no error occurs.

The EXT interrupts are not triggered :

#INT_EXT
void EXT_isr(void)
{
while (TRUE);
/* ... */
}
#INT_EXT1 // interruption des I2C IO EXTENDER
void EXT1_isr(void)
{
while (TRUE);
/* ... */
}

WORKS fine and the program continues to run.

#INT_EXT
void EXT_isr(void)
{
while (TRUE);
...
}
#INT_EXT1 // interruption des I2C IO EXTENDER
void EXT1_isr(void)
{
while (TRUE);
...
}

DOES NOT WORK (only 2 byte per trame) but the program still continues to run.
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 2:13 am     Reply with quote

The point is _you can't have INT_RDA2 as the 'only' high priority interrupt_.
The _chip does not allow this_.
If interrupt nesting is enabled INT_EXT, _will always be a high priority
interrupt
_.
This is why interrupt nesting will not fix the problem, unless you change
your design and use INT_EXT1 and INT_EXT2 instead of INT_EXT.

Shortening the time in the INT_EXT and INT_EXT1 handlers (which (of course)
is what you do when you REM the code out), is the proper solution.
VincentJ



Joined: 21 Oct 2020
Posts: 9

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 2:58 am     Reply with quote

I agree, it works if I shorten the code in the EXT interrupt handlers. But I’d like to understand.
How the duration of a non executed code can have an influence on the RDA2 interrupt behaviour ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 3:17 am     Reply with quote

Because while it is in the INT_EXT handler, it can't execute the INT_RDA2
handler. Now you say 'non executed', but I suspect it is being executed.

Some part of your code is enabling INT_EXT. Possibly an incorrect value
being written to a register, or some subroutine you have forgotten about
is resulting in the interrupt being enabled. It is being enabled somewhere....
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 4:57 am     Reply with quote

A simple test to do...

disable the INT_EXT interrupt. This is different(well should be..) than having 'no code', in the handler and the ISR enabled.

If this works, then it proves that 'somewhere' INT_EXT has been enabled and is being serviced and as Mr. T. says has a higher priority than INT_RDA2.

it's possible, if your program is huge, having 'evolved' from 'cut and paste' trials, that one of them has enabled the ISR even though 'up top' you havent'.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 5:48 am     Reply with quote

He said quite early on, that he had tried this.
I suspect something 'else' in the code is enabling the interrupt. A full search
of all the source files, would be a place to start.
VincentJ



Joined: 21 Oct 2020
Posts: 9

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 6:31 am     Reply with quote

I have a LED on my board so I tried this experience :
The LED is set ON at the beginning of the program and I added the instruction to set it OFF (not toggle) in both the EXT_INT and the EXT1_INT handlers.
When the program is running, the LED remains ON whether it is with the program that works as with the one that does not.
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 7:00 am     Reply with quote

You realise that as posted, timer3, will result in the UART being disabled.
Since TO_UART2_ON is set to 1 by the INT_RDA, after 3 characters
INT_RDA2 will be disabled, and the characters will stop receiving.
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 7:02 am     Reply with quote

I read he 'removed' code inside the ISR but not that he disabled the actual interrupt.To me there's a bg difference between the two operations.
Having a 'nulled' (do nothing) ISR ,enabled should mean the PIC might go there if the 'flag' was set,do nothing, then come back. If it's disabled, then the PIC would never go 'there' if the 'flag' was set.

I don't know if the compiler is smart enough to 'see' that with no code inside the ISR, that it will automatically disable the 'enable_ISR' code.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Thu Oct 22, 2020 7:06 am     Reply with quote

He said right at the start of his post:
Quote:

The problem continues even if I disable those interrupts.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group