//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 16F88 Rocket timer 16 November 2007
// (c) 2007 David Steeman - http://www.steeman.be
//
// This software is licenced under the GNU General Public License v2 (GPL v2, http://www.gnu.org/licenses/gpl.html)
// In summary: You are free to modify the work, as well as to copy and redistribute the work or any derivative version,
// as long as you in turn make any and all your modified source code available under the GPL v2.
//
// Input/output configuration
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <16F88.h>

#DEVICE ADC=10      // set ADC to 10 bit (output will be 10 bit (0-3FF))
#fuses INTRC_IO, MCLR, NOWDT, NOBROWNOUT, NOPROTECT, NOLVP, NODEBUG
#use delay(clock=8000000)

#include <stdlib.h>

#rom  0x2100={2,1 ,4,2 ,6,4 ,8,8, 10,16}                                         //store default delay and group settings in EEPROM when programming chip

//defines///////////////////////////////////////////////////////////////////////
//outputs
#define LED1        PIN_A1
#define LED2        PIN_A0
#define LED3        PIN_A7
#define LED4        PIN_A6

#define BUZZER      PIN_B3

#define PYRO1       PIN_B1
#define PYRO2       PIN_B0
#define PYRO3       PIN_A4
#define PYRO4       PIN_A3

//inputs
#define SELECT      PIN_B6                                                      //SELECT button
#define GROUP       PIN_B4                                                      //GROUP button
#define SET         PIN_B5                                                      //SET button
#define REED        PIN_B7                                                      //Reed switch

//configuration 
#define MAXDELAY    30                                                          //maximum delay value that can be set
#define PYROONTIME  500                                                        //time (in ms) a pyro output stays on after fired
#define BEACON      0                                                           //in beacon mode, beeper keeps buzzing even after pyros have been fired

//state machine
#define S_IDLE     0
#define S_SELECT   1
#define S_SET      2
#define S_GROUP    3
#define S_LIFTOFF  4
#define S_COUNTING 5
#define S_BEACON   6
#define S_BEEPSLOT 7


//global variables///////////////////////////////////////////////////////////////////////
unsigned int32 msecs=0, prevmsecs=0;                                           //timer counter



//RTC variables
#byte timer0low = 0x101                                                         //address of timer0 TMR0 register

void Initialize_RTC(void)
{
  setup_timer_0( RTCC_INTERNAL | RTCC_DIV_8 ); // initialize 16-bit Timer0 to interrupt exactly every 0,001s (1000Hz)
  enable_interrupts( INT_RTCC );            // Start RTC
}

#int_TIMER0
void TIMER0_isr() {
   timer0low = timer0low + 6;                                                   //set timer0 count register with correction value (for timer accuracy)
   msecs++;
}


void OutputsLow(void) {                                                         //sets all outputs to low state (makes sure pyros don't go off on startup)
   Output_low(PYRO1);
   Output_low(PYRO2);
   Output_low(PYRO3);
   Output_low(PYRO4);
   Output_low(BUZZER);
   Output_high(LED1);
   Output_high(LED2);
   Output_high(LED3);
   Output_high(LED4);
}


void main() {
   OutputsLow();

   output_toggle(BUZZER);
   delay_ms(100);
   output_toggle(BUZZER);
   delay_ms(100);
   output_toggle(BUZZER);
   delay_ms(100);
   output_toggle(BUZZER);
   delay_ms(100);

   Initialize_RTC();
   enable_interrupts( GLOBAL );

   while(TRUE) {                                                                //main loop
      if (msecs == prevmsecs+1000) {
         prevmsecs = msecs;
         output_toggle(BUZZER);
      }
   }
}


