//  swecgAB.c -- ECG simulator on PORTB LEDs; rate adjusted by PORTA switches
//  implemented and tested on Atmel STK500 with AT90S8515 in rightmost socket
// 
//  Copyleft (!C) 2003 S. Mann
//  (http://www.gnu.org/copyleft/gpl.html);
//  based on Stephen Lacy's "mirror.c"

//#include <io-avr.h> (doesn't compile when this is there)
#include <avr/io.h>
//for the above, you need to apt-get install 
#include <avr/wdt.h> 
//#include <unistd.h>

void delay(long N) {
  long n;
  for (n=0; n<N; n++);
}

int main(void) {
  unsigned char x, y, xi, yi, m, inc;
  long d;
  outp (0x00,DDRA);/* set all bits in PORTA to Direction 0 = input */
  outp (0xFF,DDRB);/* Data Direction Register: 1 means output; 0 means input*/

  //outp(0,PORTB);
  if (x==0) d=3200; /* if no switches were ever pressed, default (short reset)*/
  if (x==255) d=3200; /* if no switches were ever pressed, (long time off)*/
  while (1) {
    xi = inp(PINA); /* remembers switch input from last time programmed */
    x = 0xFF - xi; /* x from x inverse, due to common positive */
    //y = x;  /* your transformation goes here */
    //y = (x<<1) - 1;  /* your transformation, y=y(x), goes here */
    //y = 2*x-1;  /* your transformation goes here */
    //if (x==0) y=0;
    // 4000 is 44/minute
    if (x!=0) d=2000+32*(long)x; /* poor implementation of mixed mode
				  aritmetic makes it NECESSARY to
				  typecast explicitly, otherwise it
				  uses short integer arithmetic by
				  default and SW6 and 7 go fast not slowest */
    y=0;
    outp (0xFF-y,PORTB);
    delay(d); /* chaser speed controlled by switches */
    y=1;
    m=1;
    inc=1; /* increment: 1=yes; 0=decrement */
    while (m>=1) {
      yi = 0xFF - y;
      outp (yi,PORTB);
      delay(d);
      if (inc) {y=(y<<1)+1; m++;};
      if (!inc) {y=(y>>1); m--;};
      if (m==8) inc=0; /* decrement */
    }
    y=0;
    outp (0xFF-y,PORTB);
    
    delay(8*d);

    y=0;
    outp (0xFF-y,PORTB);
    delay(2*d); /* chaser speed controlled by switches */
    y=1;
    m=1;
    inc=1; /* increment: 1=yes; 0=decrement */
    while (m>=1) {
      yi = 0xFF - y;
      outp (yi,PORTB);
      delay(2*d);
      if (inc) {y=(y<<1)+1; m++;};
      if (!inc) {y=(y>>1); m--;};
      if (m==5) {inc=0; delay(4*d);}; /*change to decrement and delay at top*/
    }
    y=0;
    outp (0xFF-y,PORTB);

    delay(74*d);

  }
}

