/*  EX 2.5 Torch with timeout  */
/*  Rob Miles January 2000     */

unsigned char key ( void )
{
   unsigned char count = 0 ;
   unsigned char oldv, newv ;
   oldv = input_pin_port_b ( 0 ) ;
   while ( count < 20 )
   {
      newv = input_pin_port_b (0) ;
      if ( oldv == newv )
      {
         count++ ;
      }
      else
      {
         count = 0 ;
         oldv = newv ;
      }
   }
   return oldv ;
}


#define C1LIMIT 500
#define C2LIMIT 100

int c1, c2 ;

void start_clock (void)
{
   c1 = 0 ;
   c2 = 0 ;
}

void do_time (void)
{
   /*  if light off do nothing */
   if (input_pin_port_a(0) == 0)
	{
      return ;
   }

   /* increase first counter  */
   c1++ ;

   if ( c1 > C1LIMIT )
   {
      /*  clear first counter    */
      c1 = 0 ;

      /*  need to update the     */
      /* second counter          */
      c2++ ;

      /*  .. and check its value */
      if ( c2 > C2LIMIT )
      {
         /* turn light off here  */
               output_low_port_a(0) ;
      }
   }
}


void main ( void )
{
   /* Select the Register bank 1 */
   set_bit(STATUS,RP0);

   /* set all of PORTB for input */
     TRISB=0xff;

   /* set PORTA bit 0 as output */
     TRISA=0x1e;

   /* now use Register bank 0    */
     clear_bit(STATUS,RP0);

   /* repeat forever */
     while (1)
   {
      /* wait for the button to  */
      /* go down                 */
      while (key () == 0)
      {
         do_time () ;
      }

      /* if the light is on turn */
      /* it off                  */
      if (input_pin_port_a(0))
      {
         output_low_port_a(0);
      }
      else
      {
      /* if the light is off    */
      /* turn it on             */
         output_high_port_a(0);
         /* start the timer     */
         start_clock () ;
      }

      /* wait for the button    */
      /* to go up again         */
           while (key() == 1)
      {
         do_time () ;
      }
   }
}