/* bulb - BlinkenArea ultimate logo board
   Copyright (C) 2015 Martin Müllenhaupt <mm+bulb@netlair.de>
   Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
*/

#include <avr/io.h>

#define NUM_ZEILEN 6
#define NUM_SPALTEN 7

uint8_t frame[NUM_ZEILEN] = {0};

void showFrame()
{
  static uint8_t zeile = 0;
  static uint16_t updateCounter = 0;
  ++updateCounter;

  if (updateCounter > 100)
  {
    updateCounter = 0;
    ++zeile;
    if(zeile >= NUM_ZEILEN)
    {
      zeile = 0;
    }


    PORTD = ~(1 << zeile);
    PORTB = frame[zeile];

  }

}

void noAnimation()
{
  for(int zeile = 0; zeile < NUM_ZEILEN; ++zeile)
  {
    frame[zeile] = 0xFF;
  }
}


void blinkAnimation()
{
  static uint8_t on = 0;

  static uint16_t updateCounter = 0;
  ++updateCounter;

  if (updateCounter > 1000)
  {
    updateCounter = 0;
    if (on)
    {
      on = 0;
    }
    else
    {
      on = 1;
    }
  }

  for(int zeile = 0; zeile < NUM_ZEILEN; ++zeile)
  {
    if (on)
    {
      frame[zeile] = 0xFF;
    }
    else
    {
      frame[zeile] = 0;
    }
  }
}

void laufLichtAnimation()
{
  static uint8_t led = 0;
  static uint16_t updateCounter = 0;

  if (updateCounter > 10000)
  {
    updateCounter = 0;

    frame[led/7] = 0;
    ++led;
    if(led >= (NUM_ZEILEN*NUM_SPALTEN))
    {
      led = 0;
    }
    frame[led/7] = (1 << (led % NUM_SPALTEN) );
  }
  ++updateCounter;
}

int main(void)
{
    // PA[01] to output, low
    PORTA = 0;
    DDRA = 0x03;

    // PB[0-6] to output, low - PB7 to input, pull-up enabled
    DDRB = 0x7F;
    PORTB = 0x80;

    // PD[0-5] to output, high - PD6 to input, pull-up enabled
    DDRD = 0x3F;
    PORTD = 0x7F;

    while(1)
    {
      showFrame();
      laufLichtAnimation();
      //noAnimation();
      //blinkAnimation();
    }
}
