/*
    Title:    Cat5 Cable Checker
    Author:   Daniel Schramm
    Date:     7/2001
    Purpose:  checks CAT5 cables
    needed
    Software: AVR-GCC
    needed
    Hardware: ATS90S2313/mega on selfmade board
    Note:     To contact me, mail to
                  daniel.schramm@gmx.de
*/

#include <io.h>
#include <ina90.h>

#define OUT_B 0x07
#define OUT_D 0x73

#define ROW1 0x08		// Low for on.
#define ROW2 0x10		// High for on

typedef unsigned char u08;


const u08 ledB[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04 };
const u08 ledD[8] = { 0x01, 0x02, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00 };

int led;
u08 speed = 100;
u08 manual;

void sleep (void);

void button0 ( void )
{
  int i;
  u08 both=0;
  for (i=0; i<10000; i++) {
    if (bit_is_clear (PIND, 3))
      both=1;
  }
  
  if (both)
    manual=manual?0:1;
  else {
    if (manual) {
      led--;
      if (led < 0)
        led = 7;
    } else
    speed += 10;
  }
  if (speed > 244)
    speed = 244;
  loop_until_bit_is_set(PIND, 2);
  loop_until_bit_is_set(PIND, 3);
}

void button1 ( void )
{
  int i;
  u08 both=0;
  for (i=0; i<10000; i++) {
    if (bit_is_clear (PIND, 2))
      both=1;
  }
  
  if (both)
    manual=manual?0:1;
  else {
    if (manual) {
      led++;
      if (led > 7)
        led = 0;
    } else
    speed -= 10;
  }
  if (speed < 10)
    speed = 10;
  loop_until_bit_is_set(PIND, 2);
  loop_until_bit_is_set(PIND, 3);
}

int main (void)
{
  outp (OUT_B | ROW1 | ROW2, DDRB);
  outp (OUT_D, DDRD);
  outp (0x00, PORTB);
  outp (0x0c, PORTD);
  
  led = 0;
  manual = 0;
  
  u08 n;
  for (;;) {
    if (!manual) {
      led++;
      if (led > 7)
        led = 0;
      }

      outp (ledB[led] | ROW1 | ROW2, DDRB);
      outp (ledD[led], DDRD);
      for (n = 0; n < speed; n++)
	{
	  // je Durchlauf etwa 4,5ms
	  outp (ledB[led], PORTB);
	  outp (ledD[led] | 0x0c, PORTD);
	  sleep ();
	  
	  if (bit_is_clear (PIND, 2))
            button0();
	  if (bit_is_clear (PIND, 3))
            button1();

	  outp (0x00 | ROW2, PORTB);
	  outp (0x0c, PORTD);
	  sleep ();
	}
    }
}

void sleep (void)
{
// etwa 2,25ms
  int i;
  for (i = 0; i < 1000; i++);
}

