View previous topic :: View next topic |
Author |
Message |
cassioriguela
Joined: 25 Oct 2011 Posts: 27
|
Serial data problem with upgrade 4.099 to 4.124 |
Posted: Thu Jan 12, 2012 9:22 am |
|
|
Dear friends,
I have a problem with upgrade 4.099 to 4.124. I have a firmware that receives some data from serial interface and put it into a buffer, like EX_SISR.C. After updated, I have some data lost, i can see it because i'm sniffing serials pins. In sniffer, I receive complete packets, but when I look my buffer it's possible to see that i lost some data, generally, the last bytes.
See interrupt code:
Code: |
#define ZIGBEE_BUFFER_RX_SIZE 512
#define ZIGBEE_BUFFER_TX_SIZE 512
#define ZIGBEE_BUFFER_AUX_SIZE 512
#INT_RDA
void RDA_isr(void)
{
if(kbhit(RADIO))
{
rx[pRxFim] = fgetc( RADIO);
pRxFim = (pRxFim + 1) % ZIGBEE_BUFFER_RX_SIZE;
if (pRxInicio == pRxFim)
pRxInicio = (pRxInicio + 1) % ZIGBEE_BUFFER_RX_SIZE;
}
}
|
code for get data from buffer:
Code: |
#define zkbhit (pRxInicio != pRxFim)
int8 getCharRx(char *dado)
{
if (zkbhit == TRUE)
{
*dado = rx[pRxInicio];
pRxInicio = (pRxInicio + 1) % ZIGBEE_BUFFER_RX_SIZE;
return TRUE;
}
return FALSE;
}
|
Serial config code:
Code: |
#use rs232(STREAM=RADIO,baud=9600,parity=N,bits=8,UART1)
|
When I compile with CCS 4.099 it's work fine.
Do you have any idea about my problem ?
Thanks,
Cássio. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Jan 12, 2012 10:05 am |
|
|
i'm surprised it EVER worked
in the #use rs232 - SPECIFY RX TX pins and add ERRORS
read your manual !!!
then one messed up routine at a time:
Code: |
#INT_RDA
void RDA_isr(void)
{
byte t;
t=pRxInicio;
rx[pRxFim] = fgetc( RADIO);
pRxFim++;
if (pRxFim ==ZIGBEE_BUFFER_RX_SIZE) pRxFim=0;
if (pRxInicio==pRxFim) pRxFim=t;
// NO !!! pRxInicio = (pRxInicio + 1) % ZIGBEE_BUFFER_RX_SIZE;
}
}
int8 getCharRx(char *dado)
{
if (zkbhit ) {
*dado = rx[pRxInicio];
pRxInicio++;
if (pRxInicio ==ZIGBEE_BUFFER_RX_SIZE)pRxInicio=0;
return TRUE;
}
ELSE return FALSE; // the else was MIA !! !!!
}
|
and really getcharRX should be restructured to
ONLY be called IF zkbhit is true - |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Thu Jan 12, 2012 10:27 am |
|
|
UART1, works instead of needing to specify the TX/RX pins, so this one wouldn't cause a problem, but ERRORS, is absolutely essential. It should _only_ be omitted if you are handling errors yourself. So agree 100% about this bit.
The point about removing kbhit, is that it is extra work not needed. The interrupt _only_ triggers, when there _is_ a byte to read. Testing if a byte is available, is pointless. However Asmboy has forgotten to remove the corresponding close bracket. This needs correcting.
Add the comment that using the % operator is really to be avoided in the interrupt. It is not 'too bad' with a binary buffer size, and 8bit addresses, but with 16bit addresses here it makes many times more work than is needed. AsmBoy has fixed this, but not explained 'why'.
Agree about the buffer full handling. Much slower than ideal. However 't' needs to be an int16, not a byte, since the indexes (configuration not shown), need to be int16, for a 512 buffer size. Hopefully they _are_ int16?....
However the 'else' is not needed in the buffer handling, the earlier return means you only reach this if you haven't returned before, so gives the 'else' behaviour.
Best Wishes |
|
|
cassioriguela
Joined: 25 Oct 2011 Posts: 27
|
|
Posted: Thu Jan 12, 2012 10:37 am |
|
|
Thanks for response asmboy.
I forgot but I define pins tx e rx. See code:
Code: |
#pin_select U1Tx=PIN_B13
#pin_select U1Rx=PIN_B14
|
I'll do some tests and I will repply again. Thanks. |
|
|
cassioriguela
Joined: 25 Oct 2011 Posts: 27
|
|
Posted: Thu Jan 12, 2012 11:55 am |
|
|
Ttelmah wrote: | UART1, works instead of needing to specify the TX/RX pins, so this one wouldn't cause a problem, but ERRORS, is absolutely essential. It should _only_ be omitted if you are handling errors yourself. So agree 100% about this bit.
The point about removing kbhit, is that it is extra work not needed. The interrupt _only_ triggers, when there _is_ a byte to read. Testing if a byte is available, is pointless. However Asmboy has forgotten to remove the corresponding close bracket. This needs correcting.
Add the comment that using the % operator is really to be avoided in the interrupt. It is not 'too bad' with a binary buffer size, and 8bit addresses, but with 16bit addresses here it makes many times more work than is needed. AsmBoy has fixed this, but not explained 'why'.
Agree about the buffer full handling. Much slower than ideal. However 't' needs to be an int16, not a byte, since the indexes (configuration not shown), need to be int16, for a 512 buffer size. Hopefully they _are_ int16?....
However the 'else' is not needed in the buffer handling, the earlier return means you only reach this if you haven't returned before, so gives the 'else' behaviour.
Best Wishes |
Thanks for explanation, Ttelmah.
I did related modifications, so it seem better but, eventually, I lose some data. As I said, generally, it's last bytes of packet. Sometimes, serial interrupt stops to work too.
Somebody has a idea ?
Thanks, |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Jan 12, 2012 1:24 pm |
|
|
First I would - if possible - USE A SMALLER buffer
and then poll Zkbhit more often. |
|
|
cassioriguela
Joined: 25 Oct 2011 Posts: 27
|
|
Posted: Thu Jan 12, 2012 6:12 pm |
|
|
asmboy wrote: | First I would - if possible - USE A SMALLER buffer
and then poll Zkbhit more often. |
Thanks for response, asmboy. What are you mean about poll more often ? I'm polling as fast as possible.
Thanks, |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Jan 12, 2012 8:32 pm |
|
|
Code: |
void getCharRx(char *dado)
{
*dado = rx[pRxInicio];
pRxInicio++;
if (pRxInicio ==ZIGBEE_BUFFER_RX_SIZE)pRxInicio=0;
}
// in MAIN
void main (void){
// your init etc etc to run one time at atartup
while (1){
// your other 'main' stuff thta repeats
if (zkbhit ) getcharRX(); // this is polling ;-))
}
}
|
|
|
|
cassioriguela
Joined: 25 Oct 2011 Posts: 27
|
|
Posted: Fri Jan 13, 2012 5:12 am |
|
|
Thanks for response, asmboy.
I'm doing exactly it.
Thanks |
|
|
cassioriguela
Joined: 25 Oct 2011 Posts: 27
|
|
Posted: Fri Jan 13, 2012 6:33 am |
|
|
I don't know what is happening. Somebody has more any idea ? I'll contact CCS support.
Thanks |
|
|
cassioriguela
Joined: 25 Oct 2011 Posts: 27
|
|
Posted: Fri Jan 13, 2012 7:56 am |
|
|
Just for helping somebody helping me.
My code gives me some warnings:
>>> Warning 216 "main.c" Line 5396(0,1): Interrupts disabled during call to prevent re-entrancy: (@PUTCHAR_3_)
>>> Warning 216 "main.c" Line 5396(0,1): Interrupts disabled during call to prevent re-entrancy: (@DIVS3232A)
I think that my interrupt is going down and i'm losing some data.
Somebody has some idea why i'm getting this warnings ?
Thanks! |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Fri Jan 13, 2012 9:04 am |
|
|
Interrupts aren't parallel processes. In the main code the compiler expects that an interrupt can occur at any point in the code. Now suppose you use a function in the main code that takes a few instructions to execute then it could get interrupted. Now lets further assume that very same function is inside an ISR. To the compiler that means the function could be interrupted in main and at the same time be asked to execute in the ISR. That's what the compiler doesn't like so it protects the function in main by making it interrupt proof. The way to look at interrupts have the code as small as possible and remember that some arithmetic functions and others built into CCS are accomplished by internal function calls to keep the code size down so if they are used in an ISR they will be protected by the compiler in main.
Division exponentiation trig functions aren't good to have inside an ISR if used also in the main code due to the lockout of the interrupt while they execute in main |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Fri Jan 13, 2012 9:52 am |
|
|
Zigbee will involve interfacing to a RF transceiver. The transceiver's receiver is asynchronous. Further the whole system is half duplex. Next timing is very critical. Generally this means that the transceiver's receiver probably needs a priority interrupt and that the transceiver's transmitter needs to be managed so as not to intentionally walk over any incoming packets. Zigbee has the further disadvantage that it expects a master controller aka PAN coordinator to be powered at all times ( probably tethered to a mains supply with battery backup). Anyway the interrupt logic will be very time dependent and the PIC will probably need its timers synched to the transceiver which in turn is synched to the master controller.
Even with this I'd still assume asynchronous reception due to drift in the transmitting devices clocks. Anyway with all this going on I'd want the ISR's to be very lean and mean and I'd choose a PIC with several timers plus a good Xtal to get precise timing intervals and reduced drift overtime. Probably a 24 series to get the interrupt priority. |
|
|
cassioriguela
Joined: 25 Oct 2011 Posts: 27
|
|
Posted: Fri Jan 13, 2012 10:44 am |
|
|
Douglas Kennedy wrote: | Interrupts aren't parallel processes. In the main code the compiler expects that an interrupt can occur at any point in the code. Now suppose you use a function in the main code that takes a few instructions to execute then it could get interrupted. Now lets further assume that very same function is inside an ISR. To the compiler that means the function could be interrupted in main and at the same time be asked to execute in the ISR. That's what the compiler doesn't like so it protects the function in main by making it interrupt proof. The way to look at interrupts have the code as small as possible and remember that some arithmetic functions and others built into CCS are accomplished by internal function calls to keep the code size down so if they are used in an ISR they will be protected by the compiler in main.
Division exponentiation trig functions aren't good to have inside an ISR if used also in the main code due to the lockout of the interrupt while they execute in main |
Thanks for response, Douglas. I understand why it occurs, but I don't understand why it's occurring in my code, because i don't have any function or math calculation in my ISR.
Thanks! |
|
|
cassioriguela
Joined: 25 Oct 2011 Posts: 27
|
|
Posted: Fri Jan 13, 2012 10:48 am |
|
|
Douglas Kennedy wrote: | Zigbee will involve interfacing to a RF transceiver. The transceiver's receiver is asynchronous. Further the whole system is half duplex. Next timing is very critical. Generally this means that the transceiver's receiver probably needs a priority interrupt and that the transceiver's transmitter needs to be managed so as not to intentionally walk over any incoming packets. Zigbee has the further disadvantage that it expects a master controller aka PAN coordinator to be powered at all times ( probably tethered to a mains supply with battery backup). Anyway the interrupt logic will be very time dependent and the PIC will probably need its timers synched to the transceiver which in turn is synched to the master controller.
Even with this I'd still assume asynchronous reception due to drift in the transmitting devices clocks. Anyway with all this going on I'd want the ISR's to be very lean and mean and I'd choose a PIC with several timers plus a good Xtal to get precise timing intervals and reduced drift overtime. Probably a 24 series to get the interrupt priority. |
The interface zigbee is already OK. As I said, I'm using a sniffer on pic serials pins so, I can see what zigbee is receiving and It's totally correct. Anyway, i'm using a dsPic33F128GP802 .
I think that my interrupt is being disabled sometimes, but i don't know why.
Thanks |
|
|
|