View previous topic :: View next topic |
Author |
Message |
arga
Joined: 09 Sep 2003 Posts: 22
|
RX Buffer...futile search so far |
Posted: Tue Jan 13, 2004 2:51 am |
|
|
The problem I am having is this:
I have a circular buffer in the form of an array of 55 elements (type int). I use int_rda, which simply moves incoming data to the buffer. Not much code in the int_rda routine. I made it as simple as possible. Manipulation of received data in handled in the main().
The maximum data the PC can send at any one time is 50 bytes.
It seems that my code can only successfuly process 20 bytes.
I think it could be a timing issue.
Has anyone encountered a problem before? How did you overcome such a problem? |
|
|
Paladdin
Joined: 11 Sep 2003 Posts: 1 Location: Santander, Spain
|
|
Posted: Tue Jan 13, 2004 4:41 am |
|
|
Not much code in int_rda but... how much? It looks like you are having an overrun problem. A little example of your source code would be very useful to help finding the issue. |
|
|
neil
Joined: 08 Sep 2003 Posts: 128
|
|
Posted: Tue Jan 13, 2004 6:28 am |
|
|
Here is my ISR, this is what I would call small code and this does work. How big is yours?
#int_RDA
RDA_isr() {
rx_buffer[buff_in++]=RXREG; // direct register access, don't like getc()!!
buff_in &= BUFF_LIMIT; // Wraps around the buffer pointer to make it circular.
rx_free--; // a variable which tells me how much free space is left in the buffer.
}
Neil. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Jan 13, 2004 7:07 am |
|
|
You should be checking for errors. If you get an error and do not clear it, then the isr will stop responding. What is the value of BUFF_LIMIT? If your array is 55 bytes, then you can't do it the way you are trying. You would need a "nice" binary number like 1,2,4,8,16,32,64,128,ect... |
|
|
neil
Joined: 08 Sep 2003 Posts: 128
|
oops! |
Posted: Tue Jan 13, 2004 7:39 am |
|
|
Mark, that was my code, not arga's! I am using a binary number instead of using the % operator. Keeps things neater. I think I'm using 16 bytes, but haven't looked; This is code I did months ago.
I hadn't thought of checking for errors, I do have the ERRORS directive in the #use though. I must have been lucky, I'm using 19.2Kbaud over a 1M cable between racks. |
|
|
Ttelmah Guest
|
|
Posted: Tue Jan 13, 2004 7:43 am |
|
|
neil wrote: | Here is my ISR, this is what I would call small code and this does work. How big is yours?
#int_RDA
RDA_isr() {
rx_buffer[buff_in++]=RXREG; // direct register access, don't like getc()!!
buff_in &= BUFF_LIMIT; // Wraps around the buffer pointer to make it circular.
rx_free--; // a variable which tells me how much free space is left in the buffer.
}
Neil. |
Er.
You cannot use '&', as a way of limiting the buffer counter, unless the buffer size is a binary multiple.
Basically, if you have a _64_ byte buffer, you can use '&', but if your buffer is 55 bytes (which you originally mentioned), you have to use buffer %=55;
Best Wishes |
|
|
neil
Joined: 08 Sep 2003 Posts: 128
|
|
Posted: Tue Jan 13, 2004 7:45 am |
|
|
Hmmm, see above! |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Jan 13, 2004 9:37 am |
|
|
Didn't check the poster!!! My mistake and RJ's |
|
|
arga
Joined: 09 Sep 2003 Posts: 22
|
|
Posted: Tue Jan 13, 2004 3:20 pm |
|
|
Thanks for all your replies.
By me saying not much code in the rda routine could still be too much.
So, in view of this here's the code :
#int_rda
void serial_isr()
{
if(!flag.m_FifoFull)
{
*pFifoHead = getc();
if(oerr)
{
nTemp = RCREG;
nTemp = RCREG;
nTemp = RCREG;
cren = 0;
cren = 1;
putc(nBoardNo);
printf("Receive buffer overrun");
}
flag.m_Fifo = 1;
m = (m + 1)%MAX_RCV;
pFifoHead = aRcv + m;
if(pFifoTail == pFifoHead)
{
flag.m_FifoFull = 1;
}
}
else
{
nTemp = getc();
if(oerr)
{
nTemp = RCREG;
nTemp = RCREG;
nTemp = RCREG;
cren = 0;
cren = 1;
putc(nBoardNo);
printf("Receive buffer overrun");
}
}
}
MAX_RCV is a constant with a value of 55
pFifoTail and pFifoHead are pointers. The former points to the last memory space filled with data and the latter points to the next available memory that can be written with data.
flag.m_FifoFull is a flag that, when set, indicates that the buffer is full, which happens when pFifoTail catches up with pFifoHead.
When an overrun do occur the rx buffer is cleared. the nTemp is just a temporary buffer used for dumping whatever data is in the rx buffer when an overrun occurs. It has no other purpose.
Perhaps, the printf statement shouldn't be there. Somehow, I must send a message to the PC if an overrun occurs, but it's not sending any message at all. Transmit works for everything else. So, the tx setup is correct.
I have the ERRORS directive in the #use rs232 |
|
|
arga
Joined: 09 Sep 2003 Posts: 22
|
|
Posted: Tue Jan 13, 2004 5:01 pm |
|
|
To simplify reading the code I attached previously here are the relevant declarations made outside main()
#byte RCREG = 0x1A // offset of RCREG register
#bit oerr = 0x18.1 // OERR bit of RCSTA register
#bit cren = 0x18.4 // CREN bit of RCSTA register
The flag.m_Fifo, when set, indicates that there is data in the circular buffer. This is reset in main() once all data in the circular buffer have been processed. |
|
|
|