/*------------------------------------------------------------------------------------------------------------------------------------------------*//**
 * @file display.c
 * 
 *  Implementation of the language-independent display stuff
 *
 * \version $Id: display.c 285 2010-03-24 21:43:24Z vt $
 * 
 * \author Copyright (c) 2010 Vlad Tepesch    
 * 
 * \remarks
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 */
 /*-----------------------------------------------------------------------------------------------------------------------------------------------*/


#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>

#include "main.h"
#include "display.h"

#include "uart.h"

#include "pwm.h"


/** the amount of pwm cycles after that the dutycycle has to be adapted */
#define DISPLAY_FADE_PRESCALE ((uint8_t)((( ((uint32_t)F_TIMER2)*DISPLAY_FADE_TIME_ms )/1000)/MAX_PWM_STEPS))



static uint32_t g_oldDispState;
static uint32_t g_curDispState;
static uint32_t g_blinkState;
volatile uint8_t g_curFadeStep;


void display_setDisplayState( uint32_t i_showStates, uint32_t i_blinkstates)
{
  g_blinkState   = i_blinkstates & i_showStates;
  g_oldDispState = g_curDispState;
  g_curDispState = i_showStates;
  g_curFadeStep  = 0;
  display_outputData(g_curDispState); 
}

void display_fadeNewTime (const DATETIME* i_newDateTime)
{
  extern uint8_t pwm_table[MAX_PWM_STEPS];
  g_blinkState   = 0;
  g_oldDispState = g_curDispState;
  g_curDispState = display_getTimeState(i_newDateTime);
  g_curFadeStep  = MAX_PWM_STEPS-1;

  DISPLAY_TIMER_OCR = pgm_read_byte ( pwm_table + g_curFadeStep );

};



//void fadeTimerOCR(void)
ISR( DISPLAY_TIMER_OCR_vect )
{
  extern uint8_t pwm_table[MAX_PWM_STEPS];

  static uint8_t s_fadePrescale;
  if( g_curFadeStep )
  {
    display_outputData( g_curDispState );
    ++s_fadePrescale;
    if( s_fadePrescale ==  DISPLAY_FADE_PRESCALE){
      s_fadePrescale = 0;
      --g_curFadeStep;
      DISPLAY_TIMER_OCR = pgm_read_byte ( pwm_table + g_curFadeStep );
    }
  }
}


//void displayFadeTimerOvf (void)
ISR( DISPLAY_TIMER_OVF_vect )
{

  if( g_curFadeStep ){
    display_outputData( g_oldDispState );
  }
}

void display_blinkStep (void)
{
  if(    g_blinkState 
     && (g_curFadeStep == 0))
  {
    static uint8_t s_blinkPrescale = DISPLAY_BLINK_INT_100ms;
    if( ! (--s_blinkPrescale) )
    {
      g_curDispState ^= g_blinkState;
      display_outputData(g_curDispState);
      s_blinkPrescale = DISPLAY_BLINK_INT_100ms;
    }
  }
}


