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

Interruption priority problem
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
Manel28



Joined: 06 May 2010
Posts: 33

View user's profile Send private message

PostPosted: Fri Mar 25, 2011 6:09 am     Reply with quote

Yes, I know what you mean. A Circular buffer should be a better option.
I was talking about priorities becouse I just made a test commenting Timer1 handler code and it seems to receive all bytes without any corrupted bit even by using a linear buffer. I can assume then that the Timer1 interruption affects the 19byte packet reception.
Should I set priorities then?
The amazing world og the microcontrollers :D. Anyway thanks for your help
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Fri Mar 25, 2011 10:54 am     Reply with quote

How fast is your baud rate?.
What is your clock rate?.
Did your 'test' perform the actual buffer handling operation from the external code?. As I say, I suspect this is the real 'heart' cause of the problem....

The simplest 'priority' method, is just to declare the timer interrupt after the INT_RDA. This makes the compiler test the RDA bit _first_ in the global handler code.
Second method is to use the hardware high priority ability. Whether you can use this will depend on whether you are using any other interrupts, in particular INT_EXT.
Provided you are _not_ using INT_EXT, you just need to add "#device HIGH_INTS=TRUE" to the top of your source code, and declare INT_RDA as "#INT_RDA HIGH".

Best Wishes
Manel28



Joined: 06 May 2010
Posts: 33

View user's profile Send private message

PostPosted: Mon Mar 28, 2011 2:04 am     Reply with quote

The baud rate is 19200 bps and the clock ist 40MHz (#use delay(clock=40M, oscillator=10M) #fuses H4_SW,NOWDT,NOPROTECT,NODEBUG).
The test I´ve made consist of sending 19 bytes packets every 70ms at 19200bps. It seems to receive all data perfectly when commenting timer code and if I add it again the data get corrupted. I was thinking about disabling timer interruptions inside the rda interruption handler..may be it could be a solution
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Mar 28, 2011 2:51 am     Reply with quote

No.
All interrupts are already disabled in each other interrupt handler (unless you are using high ints).
Enable warnings when you compile the code. Now, do you have any 'interrupt disabled' warnings?. Do any appear/disappear if you enable the timer code?.
What you show for the timer, should have no effect whatsoever.
However, some different RDA code:
Code:

#define BUFFSIZE (32)
char cbuff2[BUFFSIZE];
int in_locn=0;
int out_locn=0;

#int_rda
void serial_isr(void) {                                       
 int t2,t1;
 
 do {                                                                                 
     t1=in_locn;
     cbuff2[in_locn++]=getc();                                       
     if (in_locn<out_locn) {
        t2=(BUFFSIZE+in_locn)-out_locn;
     }
     else t2=in_locn-out_locn;
     if (t2>=19) flagACKMesg=1;
     if (in_locn>=BUFFSIZE) in_locn=0;
     if (in_locn==out_locn) in_locn=t1; //Throw data if buffer overflow
  } while (kbhit());
}

Obviously you need to use code like bgetc, to read the characters from your buffer.
This does multiple things:
1) Uses a binary sized buffer larger than your message.
2) Will read multiple characters if they are waiting.
3) Sets flagACKMesg if 19 characters are in the buffer.
4) Throws away characters if the buffer overflows.

Best Wishes
Manel28



Joined: 06 May 2010
Posts: 33

View user's profile Send private message

PostPosted: Mon Mar 28, 2011 3:45 am     Reply with quote

No. I don't get any interrupt disabled warning when I compile the code. Now arises a new problem. As I said, the idea is to make a serial-ethernet converter and i was following the code of the tcp stack ex12.c.
The code when I put the serial received packets was something like:
Code:

case UDP_TX_ISREADY:
         if (UDPIsPutReady(tx_socket)) {
            
            for(bits=0;bits<=lenbuff2-1;bits++)       //lenbuff2=19
         UDPPut(cbuff2[bits]);         
            UDPFlush();        
            UDPClose(tx_socket);
            state=UDP_TX_WAIT;
           
         }
         break;

Here was pretty easy to send the 19 bytes but now I'm not sure how do i have to read the bytes from cbuff2. Sorry for so many questions but I am beginner with this stuff.
Manel28



Joined: 06 May 2010
Posts: 33

View user's profile Send private message

PostPosted: Mon Mar 28, 2011 4:43 am     Reply with quote

I add also the setup in the main function. Maybe I'm doing something wrong:
Code:

setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_XMIT_L_TO_H | SPI_CLK_DIV_4);     
enable_interrupts(INT_RDA);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);                            
set_timer1(0x5D3B);                                            
enable_interrupts(INT_TIMER1);                                            
enable_interrupts(GLOBAL);
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Mon Mar 28, 2011 8:53 am     Reply with quote

is lenbuff2 a var or a #define or const ?

in this case it would usually be a #define which would reduce the code required when compiled. if it is a var then the compiler has to treat it as a variable that may change its value which results in more code.

I doubt this is your problem, just an observation.
Manel28



Joined: 06 May 2010
Posts: 33

View user's profile Send private message

PostPosted: Mon Mar 28, 2011 9:25 am     Reply with quote

It is defined as static int const. I have just tested it again but now with circular buffer with the rda_int code Ttelmah told me and I get the same behaviour..quite strange. I am 90% sure there is something the timer1 does that corrupts the received bytes..like interruptions during receiving process and thats why the data is bad. Again I've simulated the reception commenting this lines :
Code:

setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);                      
set_timer1(0x5D3B); 
enable_interrupts(INT_TIMER1);

and it works perfectly. The thing is that I am not able to assign higher priority to rda_int. Maybe there is something I'm missing related to timer1 in PIC18f25J10. Thanks for suggestions Wayne..this is my first PIC and I'm getting crazy Smile
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Mar 28, 2011 1:53 pm     Reply with quote

I see the comment _simulated_. What simulator?. Have you tried an actual chip?.
You may be chasing a simulator problem...

Best Wishes
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Mar 28, 2011 2:54 pm     Reply with quote

Other thing is that presumably the timer code triggers _something_ externally, when you set 'temp'. What does this do?. The problem could be that something in this code, walks over part of the RAM, and corrupts values....

Best Wishes
Manel28



Joined: 06 May 2010
Posts: 33

View user's profile Send private message

PostPosted: Wed Mar 30, 2011 2:20 am     Reply with quote

Hi again, I think Im getting closer to the problem. The "temp" variable you are asking for is a flag which activates a function inside the main process. You are right. The problem is not the interruption itself but the following process executed due to temp=1. Something like:

while(TRUE) {
StackTask();
UDPTxTask();
UDPRxTask();

if(temp==1)
putc('A');
putc('B');
putc('C');
putc('D');
putc('E');
putc('F');
putc('G');
putc('H');
putc('I');


}

At the same time I'm receiving through the Rx line 19bytes. The problem in fact is the rs232 behaviour. If I make for example if(temp==2) so that putc() does not execute I receive the 19 bytes perfectly.

I have defined :

#use rs232(baud=19200, parity=O, bits=8, xmit=PIN_C6, rcv=PIN_C7)
Manel28



Joined: 06 May 2010
Posts: 33

View user's profile Send private message

PostPosted: Wed Mar 30, 2011 2:37 am     Reply with quote

I forgot to say I'm using mplab icd 2 to debug the code
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Wed Mar 30, 2011 5:09 am     Reply with quote

I'd have expected it to start working with the larger (32character) buffer.
Problem is that when 'temp==1', you may not 'see' this for the time taken to execute three tasks - how long do these take?. You need to use the debugger and _time_ the total these take to execute, and then you send 9 bytes (why not just use 'putc("ABCDEFGHI";', or a printf?), _before_ you start looking for the next packet in your code. Also, you don't show the code setting temp _back_ to zero. This should be the first line after the 'if (temp==0)' test. Now with the 32 character buffer, you can receive 18 characters after 'temp' is set, before an effective overflow would occur.

Best Wishes
Manel28



Joined: 06 May 2010
Posts: 33

View user's profile Send private message

PostPosted: Wed Mar 30, 2011 6:00 am     Reply with quote

I see the problem only when it executes putc function. I have done:
Code:

while(TRUE) {
StackTask();
UDPTxTask();
UDPRxTask();

if(temp==1)
 putc('A');
 temp=0;

}

and the problem arises. However if I do something like :
Code:

int p;
while(TRUE) {
StackTask();
UDPTxTask();
UDPRxTask();

if(temp==1)
 p=5;
 temp=0;
}

I have no problem at all. The problem comes up only if I use putc. Thats why I was wondering the thing has to do with full duplex comm settings, directive #use rs232 or my MAX488. Maybe a new PIC?
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Wed Mar 30, 2011 7:15 am     Reply with quote

Use ex_stisr.c.
Serial interrupt driven _transmit_ buffer.
Then your code only needs to load the output data, and the interrupt sends it.

Whatever you do though, the sequence should be:
Code:

if (temp==1) {
   temp=0;
   //Now read your data from the buffer, and send your reply data

}

You need to acknowledge that you have seen the characters ASAP.

Best Wishes
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