//***************************************************************************
//
//  Author(s)...: Pashgan    http://ChipEnable.Ru   
//
//  Target(s)...: ATMega8535
//
//  Compiler....: IAR 5.11A
//
//  Description.: Событийная система - практический пример. Термостат на AVR
//
//  Data........: 05.02.10 
//
//***************************************************************************
#include "event-system.h"

//кольцевой буфер
static volatile unsigned char cycleBuf[SIZE_BUF];
static unsigned char tailBuf = 0;
static unsigned char headBuf = 0;
static volatile unsigned char countBuf = 0;

//возвращает колличество событий находящихся в буфере
unsigned char ES_GetCount(void)
{
  return countBuf;  
}

//"очищает" буфер
__monitor void ES_FlushBuf(void)
{
  tailBuf = 0;
  headBuf = 0;
  countBuf = 0;
}

//взять событие
unsigned char ES_GetEvent(void)
{
  unsigned char event;
  if (countBuf > 0){                   //если приемный буфер не пустой  
    event = cycleBuf[headBuf];    //считать из него событие    
    countBuf--;                         //уменьшить счетчик 
    headBuf++;                          //инкрементировать индекс головы буфера  
    if (headBuf == SIZE_BUF) headBuf = 0;
    return event;                         //вернуть событие
  }
  return 0;
}

//положить событие
void ES_PlaceEvent(unsigned char event) 
{
  if (countBuf < SIZE_BUF){                    //если в буфере еще есть место                     
      cycleBuf[tailBuf] = event;               //кинуть событие в буфер
      tailBuf++;                                     //увеличить индекс хвоста буфера 
      if (tailBuf == SIZE_BUF) tailBuf = 0;  
      countBuf++;                                  //увеличить счетчик 
  }
} 

//*****************************************************************************
unsigned char state = GENERAL;

//обработчик прерывания таймера Т1
void HandlerEventTimer(void)
{
   GUI_Control();
}

//обработчик кнопки Enter
void HandlerEventButEnter(void)
{
  switch (state){
    case GENERAL:
      GUI_SelectTempLow();
      state = SET_TEMPERATURE_LOW;
      break;
      
    case SET_TEMPERATURE_LOW:
      GUI_SelectTempHi();
      state = SET_TEMPERATURE_HI;
      break;
      
    case SET_TEMPERATURE_HI:
      GUI_General();
      state = GENERAL;
      break;
    
    default: 
      break;
  } 
}


//обработчик кнопки Up
void HandlerEventButUp(void)
{
  switch (state){
    case SET_TEMPERATURE_LOW:
      GUI_IncTempLow();
      break;
      
    case SET_TEMPERATURE_HI:
      GUI_IncTempHi();
      break;
    
    default: 
      break;
  } 
}

//обработчик кнопки Down
void HandlerEventButDown(void)
{
  switch (state){
    case SET_TEMPERATURE_LOW:
      GUI_DecTempLow();
      break;
      
    case SET_TEMPERATURE_HI:
      GUI_DecTempHi();
      break;
    
    default: 
      break;
  } 
}

//массив указателей на функции-обработчики
__flash void (*FuncAr[])(void) = 
{
  HandlerEventButUp,  
  HandlerEventButDown,
  HandlerEventButEnter,
  HandlerEventTimer

};

void ES_Dispatch(unsigned char event)
{
  void (*pFunc)(void);
  pFunc = FuncAr[event-1];
  pFunc();
}