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

do while timeout?
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
edhaslam



Joined: 15 Jul 2005
Posts: 89
Location: UK

View user's profile Send private message

do while timeout?
PostPosted: Fri Oct 07, 2005 5:47 am     Reply with quote

Hi All,

I'm trying to implement a timeout for a do while loop that could potentially loop for ever if a character isn't received.

I've tried the following but it doesn't seem to work:

Code:

            long timeout;
            timeout=0;
           
            do
              {               
               ch=getch();
               delay_us(10);
               timeout++;             
              }
            while (ch != 'B'||(timeout>100000));


This should time out after a second, but just loops forever. Is what i'm doing correct or is there a better way to do this?

Ed
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Oct 07, 2005 5:58 am     Reply with quote

A long is 16bits
100000 would require a 32bit number
declare it as int32 instead
Ttelmah
Guest







PostPosted: Fri Oct 07, 2005 6:19 am     Reply with quote

There is also another caveat. As written, if no character arrives, it'll sit waiting in the 'getch', and never increment the 'timeout'. Use:

Code:

long timeout;

     timeout=0;
     ch=0;       
     do {               
          if (kbhit()) ch=getch();
          //Remember that the loop itself will include several
          //instructions, so depending on processor speed, the
          //'loop time', will probably be more like 20uSec
          delay_us(10);
     } while (ch != 'B' && (timeout++<50000));


To give 'exit after time', even if no charactrs arrive.

Best Wishes
Humberto



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

View user's profile Send private message

PostPosted: Fri Oct 07, 2005 6:22 am     Reply with quote

Code:

            do
              {               
               ch=getch();
               delay_us(10);
               timeout++;             
              }while (ch != 'B'||(timeout>100000));


getch() seat and wait until a char is received,
so timeout would never increment.

To get a running loop, timeout should be incremented inside a timer interrupt
handler (in background) or modifying your code adding kbhit()
Code:



            long timeout;
            timeout=10000;    //   10K !!!

            do
              {               
               if(kbhit())
                 {ch=getch();}
               else
                 {delay_us(100);   //  100us !!!
                  timeout--; }             
              }while (ch != 'B' && (timeout));




Humberto

Edited by Humberto
Hi Ttelmah, we are responding in a shared way at same time!!!


Last edited by Humberto on Fri Oct 07, 2005 6:38 am; edited 3 times in total
edhaslam



Joined: 15 Jul 2005
Posts: 89
Location: UK

View user's profile Send private message

PostPosted: Fri Oct 07, 2005 6:22 am     Reply with quote

Mark wrote:
A long is 16bits
100000 would require a 32bit number
declare it as int32 instead


Ah, yes. Silly mistake!

I've just re compiled but it still doesn't seem to jump out of the do-while loop. It must be getting stuck somewhere else in my code. Here's what I have so far. It is a comms function that send 32 blocks of 128 byte data over the serial port. Before the first block and subsequent blocks are sent, the hardware must receive a 'B' character from the PC in order to proceed:

Code:

void TxData(void)
{
#define DATA_BLOCK_SIZE      125 
#define DATA_BLOCK_NUM       31             
                                           
char ch;
int  data, B;
long block_inc=0, x=0, mem_pointer=0, i;
int32 timeout;


      delay_ms(100);                       
      putc(0x52);                             // Send 'R' char for 'Ready'

      disable_interrupts (GLOBAL);            // Turn off during async Tx

      lcd_gotoxy(2,1);                       
      printf(lcd_putc,"\f\ Downloading Data!");   // Send start message
      lcd_gotoxy(2,2);                       
      printf(lcd_putc,"Tx at 9600-8-N-1");         // Display data Tx rate
      delay_ms(1500);


      for (i=0; i<DATA_BLOCK_NUM; i++)        // 32 blocks of data to Tx
           {
           
           timeout=0;
           
            do
              {               
               ch=getch();
               delay_us(10);
               timeout++;             
              }

            while (ch != 'B'||(timeout>100000));
           
                       
               for (x=0; x<DATA_BLOCK_SIZE; x++)  // 128 bytes of data tx
                   {
                     data = read_ext_eeprom (DATA_BLOCK_SIZE +
                     mem_pointer * 256));                                       mem_pointer++;   

                     if ( data == 0x101 )          // Quick check on data integrity
                      {
                        printf(lcd_putc, "%u Out of Range\r\n", data); // Out-of-range
                        delay_ms(3000);
                      }
                     else
                       {
                         printf ("%03u", data);        // Send data sample
                       }
                         delay_ms (0.4);     
                   }                                 
           }                                           

      delay_ms(1000);
      lcd_gotoxy(3,1);                          // Print message at pos 1, line 1
      printf(lcd_putc,"\f\ Download Complete!"); // Send 'done' message to display
      delay_ms(2000);

      enable_interrupts (GLOBAL);             //Turn interrupt on again
}




Any comments welcome!

Ed
edhaslam



Joined: 15 Jul 2005
Posts: 89
Location: UK

View user's profile Send private message

PostPosted: Fri Oct 07, 2005 6:26 am     Reply with quote

You beat me to it! Many thanks guys, I can see what I'm doing now. I'll let you know how I get on.

Cheers,
Ed
Ttelmah
Guest







PostPosted: Fri Oct 07, 2005 7:03 am     Reply with quote

Hi Humberto,
It is amazing how often that happens. You post an answer, and sombody else has already posted an almost identical comment. There was a thread here a while ago, with about five answers all posted 'overlapping' like this!. Very Happy

Best Wishes
edhaslam



Joined: 15 Jul 2005
Posts: 89
Location: UK

View user's profile Send private message

PostPosted: Fri Oct 07, 2005 7:24 am     Reply with quote

Ttelmah wrote:
Hi Humberto,
It is amazing how often that happens. You post an answer, and sombody else has already posted an almost identical comment. There was a thread here a while ago, with about five answers all posted 'overlapping' like this!. Very Happy

Best Wishes


You both must have posted about a second before I did!

Ok, I've got the loop working now Smile

BUT, I still have a problem. The function txdata.c, shown below, doesn't return to the main program if I re enable the global interrupts:

Code:

void TxData(void)
{

#define DATA_BLOCK_SIZE      125             // Size of block to transmit
#define DATA_BLOCK_NUM       31              // Number of blocks to tx
                                             
char ch;
int  data, B;
long block_inc=0, x=0, mem_pointer=0, i;
int32 timeout;

      putc(0x52);                             // Send 'R' char for 'Ready'

      disable_interrupts (GLOBAL);            // Turn off during async Tx

      lcd_gotoxy(2,1);                       
      printf(lcd_putc,"\f\ Downloading Data!");
      lcd_gotoxy(2,2);                       
      printf(lcd_putc,"Tx at 9600-8-N-1");    // Display data Tx rate
      delay_ms(1500);

      for (i=0; i<DATA_BLOCK_NUM; i++)        // 32 blocks of data to Tx
           {

            timeout=0;
            ch=0;

            do
             {
               if (kbhit())                // Time out to prevent infinite loop

               ch=getch();             // Several instructions so
                                             // 'loop time' will probably be more like 20uSec                                                         
               delay_us(10);                 
              }
             while (ch != 'B' && (timeout++<30000));

 
               for (x=0; x<DATA_BLOCK_SIZE; x++)  // 128 bytes of data to Tx
                   {

                     data = read_ext_eeprom (DATA_BLOCK_SIZE + (mem_pointer * 256)); // Get sample data: 8-bit
                     mem_pointer++;                 // Keeps track of next memory 'block'

                     if ( data == 0x101 )          // Quick check on data integrity
                      {
                        printf(lcd_putc, "%u Out of Range\r\n", data); // Out-of-range
                        delay_ms(3000);
                      }
                     else
                       {
                         printf ("%03u", data);        // Send data sample
                       }
                         delay_ms (0.4);   
                   }               
           }


enable_interrupts (GLOBAL);             //Turn global interrupt on again

lcd_gotoxy(3,1);                          // Print message at pos 1, line 1
printf(lcd_putc,"\f\ Download Complete!"); // Send 'done' message


}


So if don't dissable/enable the interrup in this function, everything works fine. If I do, the program halts at the 'printf(lcd_putc,"\f\ Download Complete!");' .

Is there any reason why this might happen?

Cheeers,
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Oct 07, 2005 7:39 am     Reply with quote

A couple of comments

Code:
delay_ms (0.4);
isn't really valid. You need to use whole numbers.

What happens if you don't get a 'B', you still keep on sending and waiting for subsequent B's. You ought to have a failure mode.
edhaslam



Joined: 15 Jul 2005
Posts: 89
Location: UK

View user's profile Send private message

PostPosted: Fri Oct 07, 2005 8:12 am     Reply with quote

Mark wrote:
A couple of comments

Code:
delay_ms (0.4);
isn't really valid. You need to use whole numbers.


Good point

Quote:

What happens if you don't get a 'B', you still keep on sending and waiting for subsequent B's. You ought to have a failure mode.


Yes, the amount of Bs sent by the PC to the hardware governs the amount of blocks of data that the hardware sends to the PC.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Oct 07, 2005 8:29 am     Reply with quote

edhaslam wrote:
Mark wrote:
A couple of comments

Code:
delay_ms (0.4);
isn't really valid. You need to use whole numbers.


Good point

Quote:

What happens if you don't get a 'B', you still keep on sending and waiting for subsequent B's. You ought to have a failure mode.


Yes, the amount of Bs sent by the PC to the hardware governs the amount of blocks of data that the hardware sends to the PC.


My point is that is you timeout once, then the PC is probably not sending the B's anymore but you still keep trying. I think you should bail out or your program will appear to hang for a very long time.
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

RE:
PostPosted: Fri Oct 07, 2005 8:32 am     Reply with quote

Hi,

Just use the RS 232 receive interrupt. That way all you have to do is enable the interrupt and then sit in an inifinite Do...While loop.

thanks
arunb
edhaslam



Joined: 15 Jul 2005
Posts: 89
Location: UK

View user's profile Send private message

PostPosted: Fri Oct 07, 2005 8:40 am     Reply with quote

Quote:

My point is that is you timeout once, then the PC is probably not sending the B's anymore but you still keep trying. I think you should bail out or your program will appear to hang for a very long time.


Yes, I see what you mean. But the program does exit in practice, but as soon as I add in the enable/disable global interupts it hangs. Is it because of how the whole loop has been designed? Can you suggest a better way of doing this part of the code?

The structure is: the PC sends a 'G' character to the hardware which trips the RDA interrupt. This calls txdata() which sends an 'R' character to tell the PC it is ready to send the data. The PC then sends a B character for every block it needs to receive.

Ed


Last edited by edhaslam on Fri Oct 07, 2005 8:53 am; edited 1 time in total
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Oct 07, 2005 8:48 am     Reply with quote

Test for the B after the while loop. You can set a flag and break from the for loop or you could make the txdata return a value and just do a return(false) if you don't get a B. If you set a flag, and the bottom, you test for the flag and display a failed message. Of course you could do this inside the check for B inside the for loop.
edhaslam



Joined: 15 Jul 2005
Posts: 89
Location: UK

View user's profile Send private message

PostPosted: Fri Oct 07, 2005 8:58 am     Reply with quote

Mark wrote:
Test for the B after the while loop. You can set a flag and break from the for loop or you could make the txdata return a value and just do a return(false) if you don't get a B. If you set a flag, and the bottom, you test for the flag and display a failed message. Of course you could do this inside the check for B inside the for loop.


The strange thing is that it does seem to work if I don't dissable and enable the global interrupts?!
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