View previous topic :: View next topic |
Author |
Message |
MotoDan
Joined: 30 Dec 2011 Posts: 55
|
Packet Error Rate - INT_RDA Issue |
Posted: Wed Oct 29, 2014 4:28 pm |
|
|
Hello all,
I'm having a little trouble getting my RDA interrupt to reliably receive packets which are being transmitted from my VB app running on a PC.
My compiler is PCH V4.129 and I'm using a PIC18F which is currently running at 64 MHz. I also have two timer interrupts - Timer0 interrupts at 1 kHz and Timer4 interrupts at 25 kHz. Neither timer interrupt is doing much more than setting a flag or changing an output pin.
My RDA interrupt is set to HIGH priority and is used to fill a small buffer with a 6 byte packet. The UART is running at 115,200 baud. The packet includes a 1 byte checksum which is used to validate the packets.
The main program looks for the receipt of a valid packet flag which is set in the RDA interrupt and responds with a similar packet when a particular address and command are received.
Everything works great - Except that my packet error rate is about 15-20%. I've tried reducing the baud rate as low as 9600 without any improvement in the PER. I've also tried turning off both timers without any improvement in the PER.
I feel like the RDA interrupt/buffering is the cause because my PER goes to 0% when I dedicate the code to looping on the packet reception rather than using the RDA interrupt.
I've looked at the RX/TX on the scope and have also verified the correct packets are being sent using the scope's serial decoder. I can see when the PIC fails to reply to the previous packet.
At this point I think I'm either missing a byte here or there or my buffer pointer is getting out of sync.
Any idea on how to proceed would be much appreciated.
MotoDan |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 29, 2014 6:18 pm |
|
|
Post a short but compilable test program that we can look at. Post
everything we need, so we can drop it into MPLAB and test it. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Wed Oct 29, 2014 8:13 pm |
|
|
Have you had a look at your chip's errata? The UARTs on most PICs seem to be the subject of a lot of errata. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Thu Oct 30, 2014 1:30 am |
|
|
Agree with the comments above.
However I 'worry' about the comment about the 6byte packet.
First thing is you do realise that INT_RDA means _one_ byte is available. No more. Then what happens if the first byte of a second packet starts to arrive before the main code has processed the first?.
For a six byte receive like this, I'd be looking at something like:
Code: |
int1 have_packet=FALSE;
int8 packet[6];
#INT_RDA
void char_rx(void)
{
static int8 ctr=0;
static int8 temp_buff[6];
int8 chr;
do
{
temp_buff[ctr++]=getc();
if (ctr==6)
{
//have a packet
memcpy(packet,temp_buff,6);
have_packet=TRUE;
ctr=0;
}
} while(kbhit());
}
|
Testing the checksum etc., should be done in the main. This way you have 6 character times to handle the packet before another can arrive.
However I have to ask what distinguishes the 'start' of the packet?.
Unless there is some form of marker for this, any code will have trouble recovering if a single byte is lost. I'd normally use perhaps 'STX' and just have the interrupt reset it's counters when this is seen. |
|
|
MotoDan
Joined: 30 Dec 2011 Posts: 55
|
|
Posted: Thu Oct 30, 2014 11:59 am |
|
|
Thanks for everyone's replies and insights.
The 6 byte packet gets assembled 1 byte at a time via the RDA isr. The trick is to get the receive buffer pointer initialized before the start of each packet. In my case, the packets are commands which have a minimum of 100 ms between them. This gives me time to re-sync the receive buffer pointer before the next packet arrives. My problem with occasionally missing packets was due to this re-syncing. Originally I was going to go with a unique SOH/STX byte, but other data in the packet could keep that from working.
Two changes were made to fix the problem. First, I corrected a problem in my buffer pointer syncing. I also moved all packet parsing to the main loop. The RDA isr now only stuffs bytes into the packet and sets a packet ready flag. Main now only parses new, full packets.
The packet error rate is now 0.00%! There are actually 4 interrupts running. Two for the dual UARTs (115,200 and 4,800 baud) and two timers (1 kHz & 25 kHz). The PIC18F26K22 seems to be more than able to handle everything. I'm sure the 64 MHz clock speed is responsible for a big part of this.
Thanks again for the help. This forum is such a great source of knowledge and is a real asset to all of those in need.
Cheers!
MotoDan |
|
|
|