
/**
 *
 * Modul RMS-Bildner
 * 
 * MalZeit 06/2014
 *
 */

#include <rms_bildner.h>

#include <ad_wandler.h>

#include "debug.h"


uint16_t gSumme = 0;
uint8_t gZaehler = 0;

void RmsBildnerInit(void);
void RmsBildnerStart(void);
void RmsBildnerCallback(uint16_t analog);

uint16_t RmsBilden(void);
void RmsHoleAtomic(uint16_t *pSumme, uint8_t *pZaehler);
 
/**
 * 
 * Initialisiere Modul RMS-Bildner
 * 
 */

void RmsBildnerInit(void)
{
  AdWandlerInit();
  AdWandlerRegistriereCb(RmsBildnerCallback);
}

/**
 * 
 * Bildet arithmetischen Mittelwert aus den einzelnen RMS-Werten
 * TODO Nutzung des quadratischen Mittelwert prüfen.
 * ATTENTION: Lange Bearbeitungzeit!
 * ATTENTION: Enthält atomaren Abschnitt gegenüber AD-Wandler
 * 
 */

uint16_t RmsBilden(void)
{
  uint16_t Summe;
  uint8_t Zaehler;
  uint16_t ret;
  AD_WANDLER_START_ATOMIC;
  RmsHoleAtomic(&Summe, &Zaehler);
  AD_WANDLER_STOP_ATOMIC;
  
  ret = Summe/Zaehler;
  
  return ret;
}

/**
 * 
 * Abgesetzer Zugriff auf globale Variablen als Optimierungszaun bei atomaren Operationen
 * 
 */

void RmsHoleAtomic(uint16_t *pSumme, uint8_t *pZaehler)
{
  *pSumme = gSumme;
  *pZaehler = gZaehler;
  gSumme = 0;
  gZaehler = 0;
}

/**
 * 
 * 
 * 
 */

void RmsBildnerStart(void)
{
  AdWandlerStart();  
}

/**
 * 
 * Callback-Funktion für AD-Wandler
 * Bildet akkumulierte Summe für bis zu 64 (2^6) Werte
 * 
 */

void RmsBildnerCallback(uint16_t analog)
{
  TOGGLE_TP2;
  if (gSumme <= (0xffff - 0x03ff) && gZaehler < 255 ) { // kein Überlauf zu erwarten bei 10-Bit AD-Wandler
    gSumme += analog;
    gZaehler += 1;
  } else {
    // TODO Hier passiert ein Fehler (oder erstmal nix)
  }
  TOGGLE_TP2;
}

// EOF 
