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 support@ccsinfo.com

PCD (PIC24F) UART receive ISR question

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Oesterling



Joined: 07 Mar 2016
Posts: 13

View user's profile Send private message Visit poster's website

PCD (PIC24F) UART receive ISR question
PostPosted: Sat Mar 12, 2016 4:28 pm     Reply with quote

Hi guys.

Is this an effective way to handle the 4 deep FIFO receive data buffer ISR on a PIC24F? I know about URXISL <1:0>but even set to 00 more than one byte can be in the receive buffer (I believe.) PCD compiler version is 5.027 and my PIC is a 24FJ256GA106.

Thank you!

Code:
#use rs232(uart4,stream=bluetooth_stream,baud=19200,parity=n,bits=8,rcv=serin_rn4020,xmit=serout_rn4020,errors)

#int_rda4   // Receive Data Available (UART #4)
void serial_ISR_RN4020()
   {
   byte c;

   // the PIC24F may have up to 4 bytes in the UART buffer
   do
      {
      c = fgetc( bluetooth_stream );

      // rest of code...

      }
   while ( kbhit( bluetooth_stream ) );
   } // serial_isr()
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Mar 12, 2016 4:55 pm     Reply with quote

so long as you are OK with variable C having only the LAST char of up to 4 chars received - it's fine - but otherwise it kinda sucks - losing so many possible chars Sad

BUT that said -
if the ISR was not called until the FIFO was full - the code would be an even bigger disaster. read the example EX_SISR in the ccs driver folder
to see how to handle the data correctly on receive.

SERIOUSLY even with the glaring flaw in your code
so long as you save c somewhere FAST and prevent its over write -
you might squeak by because of this in the data sheet--
its about the timing of when the data_available ISR flag is set
Quote:

A receive interrupt will be generated when one
or more data characters have been received, as
per interrupt control bit, URXISELx.
4. Read the OERR bit to determine if an overrun
Oesterling



Joined: 07 Mar 2016
Posts: 13

View user's profile Send private message Visit poster's website

PostPosted: Sat Mar 12, 2016 9:55 pm     Reply with quote

Thanks the quick reply asmboy. I completely understand what you are saying and trust me I've never pulled more than one char at a time from int_rda in my PIC18F products but the way I interpret the dsPIC33/PIC24 Family Reference Manual "If URXISEL<1:0> = 00 or 01, an interrupt is generated each time a data word is transferred from the UARTx Receive Shift Register (UxRSR) to the receive buffer. THERE MAY BE ONE OR MORE CHARACTERS IN THE RECEIVE BUFFER." I am indeed seeing more than one character is in the UART buffer sometimes when the ISR fires which is the reason for the do while. It appears when I don't process the extra characters then the int_rda does not fire again for them.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Mar 12, 2016 11:28 pm     Reply with quote

Quote:
Is this an effective way to handle the 4 deep FIFO receive data buffer ISR on a PIC24F ?

Read this post from Ttelmah on exactly that topic:
http://www.ccsinfo.com/forum/viewtopic.php?t=54021&start=2
Oesterling



Joined: 07 Mar 2016
Posts: 13

View user's profile Send private message Visit poster's website

PostPosted: Sun Mar 13, 2016 5:46 pm     Reply with quote

Thanks PCM programmer for the link. It looks like I'm handing the ISR correctly. Smile
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Mon Mar 14, 2016 4:41 am     Reply with quote

Except possibly how much time you might be spending in the code after reading the byte. If you start doing too much here, then things could get messy...
Also (of course) how the interrupt is configured. Remember that if you set it to only interrupt when four bytes have been received, then nothing will happen if you get two (for example). Unless the data is certain to be arriving regularly (and even then, what happens if communications get interrupted), you may need to consider having a 'timeout', that triggers the serial interrupt, if the processing code has not been called for a period.
Oesterling



Joined: 07 Mar 2016
Posts: 13

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 14, 2016 7:51 am     Reply with quote

Hey Ttelmah thanks to you and everyone for the feedback. I confirmed that the ISR fires after every received byte (this is the default). My ISR code is very quick. All it does is update a rolling buffer and handle the wrap. But to be honest I have a big problem that is VERY strange so I am consolidating the code now to post. In a nutshell the UART ISR is running fine (with the extra code of course to process the extra bytes that may be in the receive buffer). My app is working great but for kicks when I change the main line code to do nothing but an endless loop of eating the rolling received buffer chars and sprintf a float32 into a string then the PIC resets. If I change the sprint to do an int32 then the PIC never resets! And the reset will only occur once serial data starts to come into the UART. No buffer overruns on the sprintf and no watchdog timer is running. I’ll post the code if anyone would be gracious enough to take a quick look and tell me I’m doing something really stupid. Thanks!
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Mon Mar 14, 2016 8:11 am     Reply with quote

Almost certainly stack overflow.
On these later PIC's, the stack is used for temporary storage inside the routines, as well as just for return addresses (the smaller PIC's don't support this). Printing, and things like FP maths can easily overflow the stack.
The real way to diagnose this 'properly', is to test the restart cause, or even more sophisticated generate an error trap on the overflow, and then the return address can be used to find out where in the code it happens. On complex code this can be really helpful.
However I'd be 99% confident on guessing this is the cause, and that you need to enlarge the stack. Actually depends on your compiler version (historically older compilers defaulted to a smaller stack size than the current ones).
Add:

#build (STACK=512)

Just before your fuses.
Oesterling



Joined: 07 Mar 2016
Posts: 13

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 14, 2016 6:08 pm     Reply with quote

Ttelmah you were 100% correct that it was a stack overflow issue. The problem went away when I increased the stack size. It’s interesting that one sprintf and a simple UART receive ISR function could cause a 256 byte stack to overflow but you explained why above. Thank you so very much!
jeremiah



Joined: 20 Jul 2010
Posts: 1322

View user's profile Send private message

PostPosted: Tue Mar 15, 2016 10:31 am     Reply with quote

From your earlier post, you were mentioning floats, which are not so trivial. I would guess some included libraries or float routines were related to the stack problem?
Oesterling



Joined: 07 Mar 2016
Posts: 13

View user's profile Send private message Visit poster's website

PostPosted: Tue Mar 15, 2016 1:26 pm     Reply with quote

Hi jeremiah. I was just doing a sprintf of a float (32 bits) to a string along with some very simple URT ISR receiver code. Increasing the stack from 256 to 512 bytes fixed the problem.
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Tue Mar 15, 2016 3:07 pm     Reply with quote

Printf uses a lot of stack space for floats.
You will find the default was 128 for that compiler version. Look at the top of the list file.
Oesterling



Joined: 07 Mar 2016
Posts: 13

View user's profile Send private message Visit poster's website

PostPosted: Tue Mar 15, 2016 8:24 pm     Reply with quote

Your are correct (again) Ttelmah. My default stack size was only 128 bytes.

I got the 256 byte size idea from the CCS docs: "STACK configures the range (start and end locations) used for the stack, if not specified the compiler uses the last 256 bytes."

I should have looked at the list file.

Thanks.
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Wed Mar 16, 2016 1:11 pm     Reply with quote

Good.

If you think about it, you are calling the printf, then this is calling FP division. Then the whole lot is calling the serial out. Even the integer version nearly uses all the available space, The FP one takes it over the edge.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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