#include "reflow.h"
#include <math.h>

// nastaveni teplot a casu
#define TEPLOTA_PREDEHREVU    120
#define DOBA_PREDEHREVU       60

#define TEPLOTA_VRCHOLU       210
#define DOBA_VRCHOLU          5

// CPU IO rozhrani
#define LCD_RS          PIN_C1      // rizeni registru LCD displeje
#define LCD_E           PIN_C2      // enable LCD displeje
#define LCD_DATA_LSB    PIN_D0      // data LCD
#include "lcd.c"

#define TL1             PIN_B3      // tlacitko S1
#define TL2             PIN_B2      // tlacitko S2
#define TL3             PIN_B1      // tlacitko S3
#define TL4             PIN_B0      // tlacitko S4

#define POWER_T4        PIN_A5      // ovladani optotriaku T4
#define POWER_T5        PIN_A4      // ovladani optotriaku T5

#define ADC_PIN         PIN_A0   //info, nelze menit - pin pouzit jako input analog
#define ADC_PIN_NC      PIN_A1   //info, nelze menit - pin pouzit jako input analog
#define REF_PIN         PIN_A3   //info, nelze menit - pin pouzit jako input reference 2.5V

// interni
#define PowerOn()    output_low(POWER_T4);output_low(POWER_T5)
#define PowerOff()   output_high(POWER_T4);output_high(POWER_T5)

// globalni promenne
struct time
{
   volatile unsigned int8  hod;
   volatile unsigned int8  min;
   volatile unsigned int8  sec;
}cas;

// funkce 
void GeneralCpuInit()
{
   output_high(POWER_T4);
   output_high(POWER_T5);
   port_b_pullups(true);
    
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);  //nepouzit
   setup_timer_1(T1_DISABLED);               //nepouzit
   setup_timer_2(T2_DIV_BY_16,249,10);       //rtc 40ms
   
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_TIMER2);
   
   setup_adc_ports(AN0_AN1_VSS_VREF);        //A0 vstup cidla, A1 nepozit, A3 - ref. 2.5V
   setup_adc(ADC_CLOCK_DIV_8);                
   SET_ADC_CHANNEL(0);                       //AN0,  PIN_A0  
}

unsigned int16 adc(void)
{
   unsigned int16 analog;
   unsigned int8  a;

   analog = 0;
   for (a=0;a<32;a++)
   {
      analog += read_adc();
      delay_us(50);
   }
   return (analog >> 5  );         // prumer = analog/32
}

int16 teplota(void)
{
   float32 Rpt;
   float32 Tpt;

   Rpt = 1.0*adc()*2350.0/1024.0;   //zapojeni OZ -> R=U/Iconst
   
   #define A 3.90802e-3
   #define B -5.802e-7
   
   Tpt = (-A + sqrt(A*A - 4*B*(1.0 - Rpt/1000.0)))/2.0/B; 

   return (unsigned int16)Tpt;
}

void baterie(void)
{
   static int8 stav=0;
   switch (stav)
   {
      case 0: stav++;
         lcd_define_char(0,LCD_CHAR_BAT0);
         break;
      case 1: stav++;
         lcd_define_char(0,LCD_CHAR_BAT20);
         break;
      case 2: stav++;
         lcd_define_char(0,LCD_CHAR_BAT40);
         PowerOff();
         break;
      case 3: stav++;
         lcd_define_char(0,LCD_CHAR_BAT60);
         break;
      case 4: stav++;
         lcd_define_char(0,LCD_CHAR_BAT80);
         break;     
      case 5: stav=0;
         lcd_define_char(0,LCD_CHAR_BAT100);
         PowerOn();
         break; 
      default: stav=0;
   }
}

#int_TIMER2
void Rtc(void)         //40ms
{
   static unsigned int8 ms40=0;
   struct time* time;
   
   time=&cas;
   if ( ++ms40 < 25) return;
   
   ms40=0;                    
    if (++(time->sec) >= 60)
    {
       time->sec=0;            //1min
        if (++(time->min) >= 60) 
      {
         time->min = 0;                    //1hod
        (time->hod)++;
      }
    }
}

void nullcas(struct time* time)
{
   disable_interrupts(INT_TIMER2);
   
   time->sec=0;
   time->hod=0;
   time->min=0;
   
   enable_interrupts(INT_TIMER2);
}

// start
void main()
{
   int8 tmp;
   
   GeneralCpuInit();
   
   PowerOff();
   
   lcd_init();
   lcd_define_char(1,LCD_CHAR_STUPEN);
   
   printf(lcd_putc,"\fbatt: \20");
   
   nullcas(&cas);
   
   for (;;){
      delay_ms(300);
   
      if (cas.sec != tmp){
         tmp=cas.sec;
         lcd_gotoxy(9,1);
         printf(lcd_putc,"%2u:%02u:%02u",cas.hod,cas.min,cas.sec);
      }
      
      baterie();
      lcd_gotoxy(1,2);
      printf(lcd_putc,"teplota: %ld\21C  ",teplota());
  }
}