//program led_blinking
// Software bei Marcel Spitz
//kurze Einführung:
/*alles hinter einem "//" oder zwischen einem "/*" und "* /" sind kommentare
 es gibt zu fast jeder funktion eine kurze einführung und wenn nicht kann man sich sie selber erklären :D */

//includes & defines 
#include <avr/io.h>  // #include bindet eine ander datei ein   
#include <stdint.h> 
#include <util/delay.h> 
#include <inttypes.h>
#include <stdio.h>
//taktfrequenz definieren
#ifndef F_CPU
#define F_CPU 16000000UL     /* Quarz mit 16 Mhz  */
#endif  
 // F_CPU ist die Taktfrequenz.

// Andere Namen für die Input und Output Ports definieren
//syntax:
//befehl / neuer name / ursprünglicher Name
//  Buttons
#define BUTTON1 PD0   
#define BUTTON2 PD1      
// LED P's
#define LEDP1 PD2      
#define LEDP2 PD3
#define LEDP3 PD4
#define LEDP4 PD5
#define LEDP5 PD6
#define LEDP6 PD7
#define LEDP7 PB0

//LED M's
#define LEDM1 PB1
#define LEDM2 PB2
#define LEDM3 PC0
#define LEDM4 PC1
#define LEDM5 PC2
#define LEDM6 PC3
#define LEDM7 PC4
#define LEDM8 PC5

//Anzeigen welche Funtionen es gibt(Prototypes)
void tas(uint8_t count, uint8_t mode);
void wait(uint8_t count, uint8_t mode);
void all_on(void);
void all_off(void);
void lrgo(uint8_t led);
void rlgo(uint8_t led);

//Hauptfunktion
int main(void)  {

  // LED Port Config
  // Konfigurieren ob der Strom raus oder rein gehen soll.
  // Die Funktion _BV() schreibt einen Bit in das entsprechende Register.
  // Alle Namen die Hier angezeigt sind sind Output Ports der rest ist Input Port
  DDRD = _BV(LEDP1) | _BV(LEDP2) | _BV(LEDP3) | _BV(LEDP4) | _BV(LEDP5) | _BV(LEDP6);    // set the visible LED pins to outputs
  DDRB = _BV(LEDP7) | _BV(LEDM1) | _BV(LEDM2);
  DDRC = _BV(LEDM3) | _BV(LEDM4) | _BV(LEDM5) | _BV(LEDM6) | _BV(LEDM7) | _BV(LEDM8);
  
  // Hier wird den beiden Inputports ein Pullup Widerstand zugewiesen der dafür sorgt, das wenn der Taster nicht
  // gedrückt ist, trotzdem ein definierbares signal herauskommt in dem Fall LOW, 0 oder false 
  PORTD = _BV(BUTTON1) | _BV(BUTTON2);  // button 1 and 2 have a pullup,

  // "&= ... ~_BV()" ist die Umkehrung zu "= ... _BV()" und bewirkt das ein Bit gelöscht wird.
  // wenn kein bit da ist ist der jeweilige Pin aus, also leuchten die LEDs nicht.
  // Hier werden alle LEDs ausgemacht.
  PORTD &= ~_BV(LEDP1) | ~_BV(LEDP2) | ~_BV(LEDP3) | ~_BV(LEDP4) | ~_BV(LEDP5) | ~_BV(LEDP6);
  PORTB &= ~_BV(LEDP7) | ~_BV(LEDM1) | ~_BV(LEDM2);
  PORTC &= ~_BV(LEDM3) | ~_BV(LEDM4) | ~_BV(LEDM5) | ~_BV(LEDM6) | ~_BV(LEDM7) | ~_BV(LEDM8);            //  LEDS are off when pin is low


  // Variablen deklaration und Wertzuweisung
  uint8_t mode;
  uint8_t count;
  uint8_t lastmode;
  uint8_t alreadyset;
  alreadyset = 100;
  lastmode = 1;
  mode = 1;
  count = 1;

  // endlosschleife beginnen, die den hauptprogrammteil bildet.
  while (1)  {
    // abfragen ob der taster gedrückt wurde
    tas(count, mode);
    //Gucken welcher Blinkmodi eingestellt ist und jenachdem die dazu gehörende Funktion ausführen.
    //ich erklär das jetzt nicht genau, wer es verstehen will liest sich die ersten paar kapitel eines tutorials durch und dann versteht ers schon.
    if(mode == 0)  {
      if(alreadyset != 0)  {
       // alle leds aus
        all_off();
        alreadyset = 0;
      }  else  {
        tas(count, mode);
      }
    }
    if(mode == 1)  {
      if(alreadyset != 1)   {
        // alle Leds an
        all_on();
        alreadyset = 1;
      }  else  {
        tas(count, mode);
      }
    }
    if(mode == 2)  {
      alreadyset = 100;
      tas(count, mode);
      // led lauflicht immer von links nach rechts
      while (count <= 57)   {
        lrgo(count);
        wait(count, mode);
        count++;
      }
      count = 1;
    }
    if(mode == 3)  {
      alreadyset = 100;
      tas(count, mode);
      //led lauflicht immer von rechts nach links
      while (count <= 57)  {
        tas(count, mode);
        rlgo(count);
        wait(count, mode);
        count++;
      }
      count = 1;
    }
    if(mode == 4)  {
      // led lauflicht zwischen der rechten und der linken seite
      if(lastmode == 1)  {
        while(count <= 57)  {
          tas(count, mode);
          rlgo(count);
          wait(count, mode);
          count++;
        }
        count = 1;
        lastmode = 2;
      }
      if(lastmode == 2)   {
        while (count <= 57)   {
          tas(count, mode);
          lrgo(count);
          wait(count, mode);
          count++;
        }
        count = 1;
        lastmode = 1;
      }
    }
  }
}

// Tasterabfragefunktion inklusive tastenentprellung
void tas(uint8_t count, uint8_t mode)  {
   if (bit_is_clear(PIND, 0))  {
        _delay_ms(50);
        _delay_ms(50);
        if (bit_is_set(PIND,0))  {
            _delay_ms(50);
            _delay_ms(50);
            count = 1;
            if( mode < 4)  {
                if( mode > 0)  {
                     mode++;
                }  else  {
                     mode = 4;
                }
            }  else  {
               mode = 0;
            }
        }
    }
    if (bit_is_clear(PIND, 1))  {
        _delay_ms(50);
        _delay_ms(50);
        if (bit_is_set(PIND, 1))  {
            _delay_ms(50);
            _delay_ms(50);
            count = 1;
            if(mode < 4 )  {
                if (mode > 0 )  {
                    mode--;
                }  else  {
                    mode = 4;
                }
            }  else  {
                mode = 0;
            }
        }
   }
}
// wartefunktion
void wait(uint8_t count, uint8_t mode)  {
   _delay_ms(250);
   tas(count, mode);
   _delay_ms(250);
}

// funktion um alle leds anzustellen
void all_on(void)  {
  PORTD = _BV(LEDP1) | _BV(LEDP2) | _BV(LEDP3) | _BV(LEDP4) | _BV(LEDP5) | _BV(LEDP6);
  PORTB = _BV(LEDP7) | _BV(LEDM1) | _BV(LEDM2);
  PORTC = _BV(LEDM3) | _BV(LEDM4) | _BV(LEDM5) | _BV(LEDM6) | _BV(LEDM7) | _BV(LEDM8);
}


// funktion um alle leds auszustellen
void all_off(void)  {
  PORTD &= ~_BV(LEDP1) | ~_BV(LEDP2) | ~_BV(LEDP3) | ~_BV(LEDP4) | ~_BV(LEDP5) | ~_BV(LEDP6);
  PORTB &= ~_BV(LEDP7) | ~_BV(LEDM1) | ~_BV(LEDM2);
  PORTC &= ~_BV(LEDM3) | ~_BV(LEDM4) | ~_BV(LEDM5) | ~_BV(LEDM6) | ~_BV(LEDM7) | ~_BV(LEDM8);
}

// funktion die das blinkmuster von der linken zur rechten seite vorgibt
void lrgo(uint8_t led)  {
  //'+++++++++++++
   if(led == 1)    {
   PORTC = _BV(LEDM8);
       PORTB = _BV(LEDP7);
     }
     if( led == 2 )   {
     PORTB &= ~_BV(LEDP7);
     PORTD = _BV(LEDP6);
     }
     if( led == 3 )   {
     PORTD &= ~_BV(LEDP6);
     PORTD = _BV(LEDP5);
     }
     if( led == 4 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP4);
     }
     if( led == 5 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP3);
     }
     if( led == 6 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP2);
     }
     if( led == 7 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP1);
     }
     if( led == 8 )   {
     PORTD &= ~_BV(LEDP1);
  PORTC &= ~_BV(LEDM8);
  PORTC = _BV(LEDM7);
     PORTB = _BV(LEDP7);
     }
     if( led == 9 )   {
     PORTB &= ~_BV(LEDP7);
     PORTD = _BV(LEDP6);
     }
     if( led == 10 )   {
     PORTD &= ~_BV(LEDP6);
     PORTD = _BV(LEDP5);
     }
     if( led == 11 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP4);
     }
     if( led == 12 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP3);
     }
     if( led == 13 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP2);
     }
     if( led == 14 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP1);
     }
     if( led == 15 )   {
     PORTD &= ~_BV(LEDP1);
  PORTC &= ~_BV(LEDM7);
  PORTC = _BV(LEDM6);
     PORTB = _BV(LEDP7);
     }
     if( led == 16 )   {
     PORTB &= ~_BV(LEDP7);
     PORTD = _BV(LEDP6);
     }
     if( led == 17 )   {
     PORTD &= ~_BV(LEDP6);
     PORTD = _BV(LEDP5);
     }
     if( led == 18 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP4);
     }
     if( led == 19 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP3);
     }
     if( led == 20 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP2);
     }
     if( led == 21 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP1);
     }
     if( led == 22 )   {
     PORTD &= ~_BV(LEDP1);
  PORTC &= ~_BV(LEDM6);
  PORTC = _BV(LEDM5);
     PORTB = _BV(LEDP7);
     }
     if( led == 23 )   {
     PORTB &= ~_BV(LEDP7);
     PORTD = _BV(LEDP6);
     }
     if( led == 24 )   {
     PORTD &= ~_BV(LEDP6);
     PORTD = _BV(LEDP5);
     }
     if( led == 25 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP4);
     }
     if( led == 26 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP3);
     }
     if( led == 27 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP2);
     }
     if( led == 28 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP1);
     }
     if( led == 29 )   {
     PORTD &= ~_BV(LEDP1);
  PORTC &= ~_BV(LEDM5);
  PORTC = _BV(LEDM4);
     PORTB = _BV(LEDP7);
     }
     if( led == 30 )   {
     PORTB &= ~_BV(LEDP7);
     PORTD = _BV(LEDP6);
     }
     if( led == 31 )   {
     PORTD &= ~_BV(LEDP6);
     PORTD = _BV(LEDP5);
     }
     if( led == 32 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP4);
     }
     if( led == 33 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP3);
     }
     if( led == 34 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP2);
     }
     if( led == 35 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP1);
     }
     if( led == 36 )   {
     PORTD &= ~_BV(LEDP1);
  PORTC &= ~_BV(LEDM4);
  PORTC = _BV(LEDM3);
     PORTB = _BV(LEDP7);
     }
     if( led == 37 )   {
     PORTB &= ~_BV(LEDP7);
     PORTD = _BV(LEDP6);
     }
     if( led == 38 )   {
     PORTD &= ~_BV(LEDP6);
     PORTD = _BV(LEDP5);
     }
     if( led == 39 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP4);
     }
     if( led == 40 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP3);
     }
     if( led == 41 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP2);
      }
     if( led == 42 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP1);
     }
     if( led == 43 )   {
     PORTD &= ~_BV(LEDP1);
  PORTC &= ~_BV(LEDM3);
  PORTB = _BV(LEDM2);
     PORTB = _BV(LEDP7);
      }
     if( led == 44 )   {
     PORTB &= ~_BV(LEDP7);
     PORTD = _BV(LEDP6);
     }
     if( led == 45 )   {
     PORTD &= ~_BV(LEDP6);
     PORTD = _BV(LEDP5);
     }
     if( led == 46 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP4);
     }
     if( led == 47 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP3);
     }
     if( led == 48 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP2);
     }
     if( led == 49 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP1);
     }
     if( led == 50 )   {
     PORTD &= ~_BV(LEDP1);
  PORTB &= ~_BV(LEDM2);
  PORTB = _BV(LEDM1);
     PORTB = _BV(LEDP7);
     }
     if( led == 51 )   {
     PORTB &= ~_BV(LEDP7);
     PORTD = _BV(LEDP6);
     }
     if( led == 52 )   {
     PORTD &= ~_BV(LEDP6);
     PORTD = _BV(LEDP5);
     }
     if( led == 53 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP4);
     }
     if( led == 54 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP3);
     }
     if( led == 55 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP2);
     }
     if( led == 56 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP1);
     }
     if( led == 57 )   {
     PORTD &= ~_BV(LEDP1);
  PORTB &= ~_BV(LEDM1);
  }
}

//funktion die das blinkmuster von der rechten zur linken seite vorgibt.
void rlgo(uint8_t led)  {
  if( led == 1 )   {
  PORTB = _BV(LEDM1);
     PORTD = _BV(LEDP1);
     }
     if( led == 2 )   {
     PORTD &= ~_BV(LEDP1);
     PORTD = _BV(LEDP2);
     }
     if( led == 3 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP3);
     }
     if( led == 4 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP4);
     }
     if( led == 5 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP5);
     }
     if( led == 6 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP6);
     }
     if( led == 7 )   {
     PORTD &= ~_BV(LEDP6);
     PORTB = _BV(LEDP7);
     }
     if( led == 8 )   {
     PORTB &= ~_BV(LEDP7);
  PORTB &= ~_BV(LEDM1);
  PORTB = _BV(LEDM2);
     PORTD = _BV(LEDP1);
     }
     if( led == 9 )   {
     PORTD &= ~_BV(LEDP1);
     PORTD = _BV(LEDP2);
     }
     if( led == 10 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP3);
     }
     if( led == 11 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP4);
     }
     if( led == 12 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP5);
     }
     if( led == 13 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP6);
     }
     if( led == 14 )   {
     PORTD &= ~_BV(LEDP6);
     PORTB = _BV(LEDP7);
     }
     if( led == 15 )   {
     PORTB &= ~_BV(LEDP7);
  PORTB &= ~_BV(LEDM2);
  PORTC = _BV(LEDM3);
     PORTD = _BV(LEDP1);
     }
     if( led == 16 )   {
     PORTD &= ~_BV(LEDP1);
     PORTD = _BV(LEDP2);
     }
     if( led == 17 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP3);
     }
     if( led == 18 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP4);
     }
     if( led == 19 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP5);
     }
     if( led == 20 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP6);
     }
     if( led == 21 )   {
     PORTD &= ~_BV(LEDP6);
     PORTB = _BV(LEDP7);
     }
     if( led == 22 )   {
     PORTB &= ~_BV(LEDP7);
  PORTC &= ~_BV(LEDM3);
  PORTC = _BV(LEDM4);
     PORTD = _BV(LEDP1);
     }
     if( led == 23 )   {
     PORTD &= ~_BV(LEDP1);
     PORTD = _BV(LEDP2);
     }
     if( led == 24 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP3);
     }
     if( led == 25 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP4);
     }
     if( led == 26 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP5);
     }
     if( led == 27 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP6);
     }
     if( led == 28 )   {
     PORTD &= ~_BV(LEDP6);
     PORTB = _BV(LEDP7);
     }
     if( led == 29 )   {
     PORTB &= ~_BV(LEDP7);
  PORTC &= ~_BV(LEDM4);
  PORTC = _BV(LEDM5);
     PORTD = _BV(LEDP1);
     }
     if( led == 30 )   {
     PORTD &= ~_BV(LEDP1);
     PORTD = _BV(LEDP2);
     }
     if( led == 31 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP3);
     }
     if( led == 32 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP4);
     }
     if( led == 33 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP5);
     }
     if( led == 34 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP6);
     }
     if( led == 35 )   {
     PORTD &= ~_BV(LEDP6);
     PORTB = _BV(LEDP7);
     }
     if( led == 36 )   {
     PORTB &= ~_BV(LEDP7);
  PORTC &= ~_BV(LEDM5);
  PORTC = _BV(LEDM6);
     PORTD = _BV(LEDP1);
     }
     if( led == 37 )   {
     PORTD &= ~_BV(LEDP1);
     PORTD = _BV(LEDP2);
     }
     if( led == 38 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP3);
     }
     if( led == 39 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP4);
     }
     if( led == 40 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP5);
     }
     if( led == 41 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP6);
     }
     if( led == 42 )   {
     PORTD &= ~_BV(LEDP6);
     PORTB = _BV(LEDP7);
     }
     if( led == 43 )   {
     PORTB &= ~_BV(LEDP7);
  PORTC &= ~_BV(LEDM6);
  PORTC = _BV(LEDM7);
     PORTD = _BV(LEDP1);
     }
     if( led == 44 )   {
     PORTD &= ~_BV(LEDP1);
     PORTD = _BV(LEDP2);
     }
     if( led == 45 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP3);
     }
     if( led == 46 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP4);
     }
     if( led == 47 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP5);
     }
     if( led == 48 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP6);
     }
     if( led == 49 )   {
     PORTD &= ~_BV(LEDP6);
     PORTB = _BV(LEDP7);
     }
     if( led == 50 )   {
     PORTB &= ~_BV(LEDP7);
  PORTC &= ~_BV(LEDM7);
  PORTC = _BV(LEDM8);
     PORTD = _BV(LEDP1);
      }
     if( led == 51 )   {
     PORTD &= ~_BV(LEDP1);
     PORTD = _BV(LEDP2);
     }
     if( led == 52 )   {
     PORTD &= ~_BV(LEDP2);
     PORTD = _BV(LEDP3);
     }
     if( led == 53 )   {
     PORTD &= ~_BV(LEDP3);
     PORTD = _BV(LEDP4);
     }
     if( led == 54 )   {
     PORTD &= ~_BV(LEDP4);
     PORTD = _BV(LEDP5);
     }
     if( led == 55 )   {
     PORTD &= ~_BV(LEDP5);
     PORTD = _BV(LEDP6);
     }
     if( led == 56 )   {
     PORTD &= ~_BV(LEDP6);
     PORTB = _BV(LEDP7);
     }
     if( led == 57 )   {
     PORTB &= ~_BV(LEDP7);
  PORTC &= ~_BV(LEDM8);
     }
}







