#include "main.h"

#include <string.h>

#define LED PIN_E1  
#define CE  PIN_E2

#define SEL0   PIN_E0   // external counter division ratio
#define SEL1   PIN_E1   // external counter division ratio
#define MR     PIN_E2   // external counter master reset
#define CLKI   PIN_C0   // internal counter input
#define BEEP   PIN_C3   // buzzer

unsigned int32 count;


int8 buffer[0x10];   // I2C buffer     
int8 address;

unsigned int16 of=0; // count of overflow

const char cmd[40]={0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x80, 0x84, 0x1E, 0x00, 0xE0, 0xC8, 0x10, 0x00, 0x40, 0x42, 0x0F, 0x00, 0xA0, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x00, 0x00, 0x12, 0x03};

#INT_SSP
void ssp_interupt ()
{
   BYTE incoming, state;

   state = i2c_isr_state();
   
   if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      if(state == 1)                     //First received byte is address
      {
         address = incoming;
         if (incoming == 2)
         {
            buffer[0]=make8(count,0);
            buffer[1]=make8(count,1);
            buffer[2]=make8(count,2);
            buffer[3]=make8(count,3);
         }
      }
      if(state == 2)                     //Second received byte is data
         buffer[address] = incoming;
         
      
   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(buffer[address]);
   }
}


#int_EXT  // Interrupt from 1PPS
void  EXT_isr(void) 
{
   unsigned int16 countH;
   unsigned int8  countL;
   char countS[10], a[4], b[4], c[4];  // strings for printing results
   
   countL=0;
   countH=get_timer1();    // read internal counter
   output_low(SEL0);
   output_low(SEL1);
   countL=input(CLKI);     // read bit 0 of external counter
   output_high(SEL0);
   output_low(SEL1);
   countL|=input(CLKI)<<1; // read bit 1 of external counter
   output_low(SEL0);
   output_high(SEL1);
   countL|=input(CLKI)<<2; // read bit 2 of external counter
   output_high(SEL0);
   output_high(SEL1);
   countL|=input(CLKI)<<3; // read bit 3 of external counter

   output_low(MR);   // External counter Master Reset
   output_high(MR);
   
   set_timer1(0);    // Internal counter reset
   
   count=((unsigned int32)of<<20)+((unsigned int32)countH<<4)+(unsigned int32)countL; // concatenate 

   sprintf(countS,"%09Lu", count);  // engeneering values conversion
   strncpy(a, countS, 3); a[3]='\0';
   strncpy(b, &countS[3], 3); b[3]='\0';
   strncpy(c, &countS[6], 3); c[3]='\0';
   
   printf("%s\r\n", countS);                    // output to RS232

   output_toggle(BEEP); // cvak...

   of=0; // reset overflow counter
}

#int_TIMER1  // Interrupf from overflow
void  TIMER1_isr(void) 
{
   of++;
}


/*#int_TIMER2 // every 10 ms
void  TIMER2_isr(void) 
{
   output_low(CE);
   count=get_timer1();
   set_timer1(0);
   output_high(CE);
}*/

 
void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
//   setup_wdt(WDT_144MS);
   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
   setup_timer_2(T2_DIV_BY_16,196,16);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   delay_ms(1000);
   int n;
   for (n=0;n<40;n++) putc(cmd[n]); // setup GPS

   printf("cvak...\r\n");
   
   ext_int_edge( L_TO_H );       // set 1PPS active edge
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_SSP); 
//   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);    

   while(true)
   {      
/*     output_high(LED);
     delay_ms(999);
     output_low(LED);
     delay_ms(999);
     printf("%X %X %X %X\r\n", buffer[0],buffer[1],buffer[2],buffer[3]);
*/
   }
}