
/**
 * 
 * Mit dem Systemtimer ein Flag mit einer Rate von 20Hz setzt, das die Auswertung des RMS-Wertes anstößt.
 * Bei jeder Auswertung auch den Adressencoder auslesen.
 * 
 * 
 */


// Standard libraries
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>


// Own libraries
#include "led_balken.h"
#include "systemzeitgeber.h"
#include "rms_bildner.h"
#include "dmx_steuerung.h"

#include "debug.h"
#include "led_ports.h"
#define TRUE 1
#define FALSE 0

#ifndef DDR_OFFSET
  #define DDR_OFFSET(X) (*(&X-1))
#endif
#ifndef PIN_OFFSET
  #define PIN_OFFSET(X) (*(&X-2))
#endif


/**
 * 
 * Module die den Systemzeitgeber benötigen:
 * * Main
 * * Taster
 * 
 */


// Globale Variablen
volatile uint8_t gAuswertungRMS = FALSE;

void AuswertungTimerCb(void);
uint8_t holegAuswertungRMS(void);
void  DeadIoInit(void);
void GehSchlafen(void);

int main(void) {
  // Init
  SystemzeitgeberInit();
  RmsBildnerInit();
  LedBalkenInit();
  DmxSteuerungInit();
  
  SystemzeitgeberRegistriereCb(AuswertungTimerCb, 25);
  DeadIoInit();
  
  LedBalkenSetzeWert(0xffff);
  _delay_ms(500);
  
  // Start
  sei();
  SystemzeitgeberStart();
  RmsBildnerStart();
  DmxSteuerungStart();
  LedBalkenSetzeWert(0);

  
  while(1) {
    uint8_t auswertung;
    uint16_t rms = 0;
   
// Schlafe im Idle-Mode    
    GehSchlafen();
    
    
    SYSTEMZEITGEBER_ATOMIC_START;
    auswertung = holegAuswertungRMS();
    SYSTEMZEITGEBER_ATOMIC_ENDE;
    if(auswertung != FALSE) {
      TOGGLE_TP1;
      // RMS behandeln
      rms = RmsBilden();
      
      LedBalkenSetzeWert(rms);
      DmxSteuerungSetzeWert(rms);
      TOGGLE_TP1;
    }
    
    
    
  }
  
  
}

/**
 * 
 * 
 * 
 */


void DeadIoInit(void)
{
  // TODO ISP
  // Ausgang
  DDR_OFFSET(PORTC) |= _BV(PC4); 
  DDR_OFFSET(PORTD) |= _BV(PD0); 
  DDR_OFFSET(PORTB) |= _BV(PB2); 

  // Aus
  PORTC &= ~_BV(PC4); 
  PORTD &= ~_BV(PD0); 
  PORTB &= ~_BV(PB2); 

  
}

/**
 * 
 * 
 * 
 * 
 */

void GehSchlafen()
{
  sleep_enable();
  set_sleep_mode(SLEEP_MODE_IDLE); // wakes up from system_timer
  sleep_mode();
  sleep_disable();
}

/**
 * 
 * ATOMIC
 *
 * Abgesetzter Zugriff auf globale Variable als Optimierungszaun bei atomaren Operationen
 * 
 */ 

uint8_t holegAuswertungRMS(void)
{
  uint8_t ret = gAuswertungRMS;
  gAuswertungRMS = FALSE;
  return ret;
}

/**
 * 
 * 
 * 
 */

void AuswertungTimerCb(void)
{
      TOGGLE_TP2;
  gAuswertungRMS = TRUE;
      TOGGLE_TP2;
}