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

Questions About Standard Serial ISR

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



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

Questions About Standard Serial ISR
PostPosted: Tue Oct 25, 2005 4:34 pm     Reply with quote

Hello All,

I've been trying to solve a problem with a set of serial radios. I got deep into the serial ISR and figured I'd be alot better off if I understood what was happening. (Luckily, I think the problem is hardware, but I still have questions...)

Here's the code:

Code:
/*******************************
      Serial ISR Support
*******************************/
#define BUFFER_SIZE 32
byte buffer[BUFFER_SIZE];
byte next_in = 0;
byte next_out = 0;

#define bkbhit (next_in!=next_out)

char cmd_str[20];

/*******************************
    Serial Receive Buffer ISR
*******************************/
#int_rda
void serial_isr()
{
   int t;
   buffer[next_in]=getc();
   t = next_in;
   next_in = (next_in+1) % BUFFER_SIZE;
   if(next_in == next_out)
   next_in = t;           // Buffer full !!
}

byte bgetc()
{
   byte c;
   while(!bkbhit) ;
   c = buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}

void get_cmd_str(char * s, int max) {
   int len;
   char c;

   max--;
   len = 0;

   do {
      c = bgetc();
      if(c > 0x00) {
         if(len < max) {
            s[len++] = c;
         }
      }
   }
   while(bkbhit);
   s[len]= 0x00;
}



main() {
/******* Serial Buffer Retrieve ***********/
   if(bkbhit) {
      delay_ms(50);              //Delay allows full string to arrive
      get_cmd_str(cmd_str, 10);
   }
   /******* End Serial Buffer Retrieve ***********/
}


My general understanding of what's happening:

1. Character arrives in PIC UART
2. int_rda is triggered (every time a character arrives, no?)
3. serial_isr() is executed and arriving character is put in buffer[next_in]

Steps 1 - 3 happen with each character arrival.

4. If there is a disagreement between the number of characters received and the number fetched (bkbhit) then get_cmd_str() is executed.

Questions:

What is the purpose of:
Code:
while(bkbhit);

in bgetc()?

What is the meaning of "bkbhit" is it a mnemonic for something?

Thanks,

John
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

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

PostPosted: Tue Oct 25, 2005 4:56 pm     Reply with quote

It is really while(!bkbhit);
While not bkbhit, wait forever.
OR
while (not(next_in!=next_out) wait forever
OR
while(next_in==next_out) wait forever
OR
if nothing in the buffer ie: indexes are the same, wait forever

Quote:

byte bgetc()
{
byte c;
while(!bkbhit) ;
c = buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}



So if you call bgetc and the indexes are the same you will sit there and WAIT untill the RX-ISR breaks you out saves a byte in the buffer, increments an index and next_in!=next_out
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Tue Oct 25, 2005 5:08 pm     Reply with quote

OK, now I get the picture. I didn't put 2 and 2 together with that statement. I just assumed it wasn't doing anything. But really, bkbhit gets updated in each interrupt.

Thanks,

John
neil



Joined: 08 Sep 2003
Posts: 128

View user's profile Send private message

Adding to this...
PostPosted: Wed Oct 26, 2005 6:44 am     Reply with quote

Just thought I'd elaborate a bit.
The kbhit() function is from desktop computer/terminal architecture. It detects when a key on the keyboard has been hit (kbhit) by checking for data in the keyboard buffer. I don't think this applies to serial comms on a PC for example, but CCS have used it as such for their compiler.
The 'bkbhit' function (b for buffer?) is just a re-written one to check your 'home-made' buffer. You can't name it 'kbhit' as this is already a built in function.

Also, with the serial ISR, and bgetc() as the buffer is a binary value (32), you can save on machine cycles (unless the compiler already optimises this for you?) by using the AND operator.
Code:
next_in = (next_in+1) & (BUFFER_SIZE-1);

Note the use of "buffer size -1" You want the pointer to wrap around from 31, back to 0, not 32 You don't need this with the % operator, as 32%32=0 which gives the same result as 32&31=0 but I think using the & operator will be more code efficient. You can define "buff_limit" as "buff_size-1" and also save on a subtraction.

eg.
0 & 31 = 0
1 & 31 = 1
...
31 & 31 = 31
32 & 31 = 0
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Wed Oct 26, 2005 8:20 am     Reply with quote

Quote:

I've been trying to solve a problem with a set of serial radios.


Just a small suggestion for your brain care:

First of all, try to establish a reliable wired communication procedure.
After that, and only after that add the RF link.

Tell us your result.

Humberto
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Wed Oct 26, 2005 9:23 am     Reply with quote

Neil,

Thanks for the background. That's what I was looking for. I'm the proverbial 4 year old when it comes to C. Why? ....... Why?....... Why?

I'll work on optimization if I need to. I tend to use larger parts at higher speeds to do fairly simple things ( a technique fairly forgiving of the optimizationally challenged.)

Humberto,

Thanks for the suggestion. I normally put a serial port on every board for development. I had the radios working with a previous, non-packetized, scheme but when I made the changes it broke. Trouble shooting has been complicated by the fact the problem is with one of the radios... I think. I may have sent the radio into lala land, and I don't have a carrier board to reset it....should get one in a couple of days. I have two other radios that don't exhibit the problem.

The actual problem is:

I put a LED flash in the MAIN WHILE routine.....

Code:
if(bkbhit) {                          //something in RX buffer

        output_high(LED3);
        delay_ms(500);
        output_low(LED3)


It hangs without having TXed it anything. So I'm pairing everything done right now to retry just some simple TX and RX routines to recheck my hardware....

I'll report back.

Thanks,

John
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Wed Oct 26, 2005 10:02 am     Reply with quote

Update:

Bad radio.... Comms are working with simple tx and rx code. Now I'm trying to debug some packetized comms (checksum routine) with nothing but a flashing LED. Argggghhhhh.

Code:
while(TRUE) {

   strike_head_on_wall();

}


John
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