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

Serial data problem with upgrade 4.099 to 4.124
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
cassioriguela



Joined: 25 Oct 2011
Posts: 27

View user's profile Send private message

Serial data problem with upgrade 4.099 to 4.124
PostPosted: Thu Jan 12, 2012 9:22 am     Reply with quote

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

View user's profile Send private message AIM Address

PostPosted: Thu Jan 12, 2012 10:05 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 12, 2012 10:27 am     Reply with quote

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'. Smile

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

View user's profile Send private message

PostPosted: Thu Jan 12, 2012 10:37 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 12, 2012 11:55 am     Reply with quote

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'. Smile

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

View user's profile Send private message AIM Address

PostPosted: Thu Jan 12, 2012 1:24 pm     Reply with quote

First I would - if possible - USE A SMALLER buffer
and then poll Zkbhit more often.
cassioriguela



Joined: 25 Oct 2011
Posts: 27

View user's profile Send private message

PostPosted: Thu Jan 12, 2012 6:12 pm     Reply with quote

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

View user's profile Send private message AIM Address

PostPosted: Thu Jan 12, 2012 8:32 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 13, 2012 5:12 am     Reply with quote

Thanks for response, asmboy.
I'm doing exactly it.

Thanks
cassioriguela



Joined: 25 Oct 2011
Posts: 27

View user's profile Send private message

PostPosted: Fri Jan 13, 2012 6:33 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 13, 2012 7:56 am     Reply with quote

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

View user's profile Send private message AIM Address

PostPosted: Fri Jan 13, 2012 9:04 am     Reply with quote

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

View user's profile Send private message AIM Address

PostPosted: Fri Jan 13, 2012 9:52 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 13, 2012 10:44 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 13, 2012 10:48 am     Reply with quote

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