/*******************************************************
FILE:     movebar.c

DESCRIPTION: Pot connected to PICchip controls moving
bar on the PC. Uses timer interrupt for precise 
sampling rate. 

REVISION HISTORY:  
*******************************************************/
//--Includes

#include <16f88.h>
#device ADC=10             // for 10-bit ADC results

//--Setup commands

#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOWRT,NOLVP  // internal oscillator
#id 0x1234                     // 4 digit id
#use standard_io(A)
#use standard_io(B)
//#use fast_io(A)
//#use fast_io(B)
#use delay(clock=8000000)      // declare clock speed
#use rs232(baud=19200,xmit=PIN_B5,rcv=PIN_B2) // USART
#priority rda, rtcc  //don't want to miss incoming info


//--Pin definitions
#define LED      PIN_B0   // LED

//--Defines
#define AD_CHAN_DELAY  20     // adc channel change delay (uS)
#define BASECOUNT 100         // base count for timer 0
                              // = 156 ticks = 100.1 Hz @ div_128
                              // or, 12=244 ticks = 128 Hz @ div_64
                              // valid for 8 MHz osc

//--Global variables
int1 hflag, senddataflag;
int8 cmd,data;

/*******************************************************
  Functions
*******************************************************/

/*******************************************************
  Send_data()
  Sends a 2-byte frame to host, 10-bit data, 6-bit cmd.
  Byte 0 has lower 8 bits of data, byte 1 has high 2 bits of
  data and 6 bit cmd. 
*******************************************************/

void send_data(int8 cmd, int16 data) {

  putc(make8(data,0));   
  putc((data >> 8) + (cmd << 2)); 
}


/*******************************************************
  flash_led()
  Flash LED n times 
*******************************************************/

void flash_led(int8 n) {
  int8 i;
  for (i=0;i<n;i++) {
    output_high(LED);
    delay_ms(100);
    output_low(LED);
    delay_ms(300);
  }
}

/*******************************************************
  Serial port character receive interrupt service routine
  Incoming data is a 2 byte frame, byte 1 = cmd, byte 2 = data.
*******************************************************/

#int_rda
void serial_isr(void)
{
  cmd = getc();       // get data
  data = getc();
  hflag=1;            // set flag for main program
}


/*******************************************************
  Timer interrupt service routine. Sample ADC and
  transmit to host if host wants it. 
*******************************************************/

#int_rtcc
void rtcc_isr(void)
{
  set_timer0(BASECOUNT);      //reset counter
  if (senddataflag) 
    send_data(0,read_adc());  //convert and send
}


/*******************************************************
  Main starts here
*******************************************************/

void main(void)
{
  setup_oscillator(OSC_8MHZ);

//-------Set direction registers

//  set_tris_a(0xFF);   // a is all inputs (for adc)
//  set_tris_b(0xC0);   // b7,b6 in, rest out

//------ADC setup 
  setup_adc_ports(sAN0 | VSS_VDD);  // AN0 and voltage range see file 16f88.h for options
  setup_adc(ADC_CLOCK_DIV_16); // TAD = 2.0 uS if chip clock 8 MHz
  set_adc_channel(0);         // select channel 0
  delay_us(AD_CHAN_DELAY);    // wait to settle
  
//------Timer 0 setup
 setup_timer_0(RTCC_INTERNAL | RTCC_DIV_128); //ticks every 64 uS

//-------Flash led a few times

  flash_led(2);
  
//-------enable interrupts
                    
  enable_interrupts(INT_RDA);    // receive serial char
  enable_interrupts(INT_RTCC);   // timer
  enable_interrupts(GLOBAL);    

//-------loop forever checking for host commands

  while (TRUE) {
    if (hflag) {            // handle host command
      hflag=0;
      switch (cmd) {        // branch on host command
        case 1:             // start sending data
          senddataflag=TRUE;
          break;
        case 2:             // stop sending data
          senddataflag=FALSE;
          break;
        case 3:             // flash led
          flash_led(data);
          break;        
        case 255:           // are you there?
          send_data(1,1);
          break;
        default:
          break;
      }
    }     
  }
}


