
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Load cell amplifier & D/A converter
// (c) 2008 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.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <18F2550.h>
#DEVICE ADC=10                                                                  //set ADC to 10 bit (output will be 10 bit (0-3FF))
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN           //configure a 20MHz crystal to operate at 48MHz
#use delay(clock=48000000)
#include <usb_cdc.h>

// Defines /////////////////////////////////////////////////////////////////////
#define LED1    PIN_A5
#define ADC_IN  PIN_A0

#define SAMPLESPEED 6000                                                        // 6000 Hz

#if SAMPLESPEED == 1000
//#define TMR0prescaler   RTCC_DIV_64                                             // 997,34 Hz
//#define TMR0preload   68                                                        // 997,34 Hz
#endif
#if SAMPLESPEED == 2000
//#define TMR0prescaler   RTCC_DIV_64                                             // 1994,68 Hz
//#define TMR0preload   162                                                       // 1994,68 Hz
#endif
#if SAMPLESPEED == 3000
//#define TMR0prescaler   RTCC_DIV_32                                             // 3000 Hz
//#define TMR0preload   131                                                       // 3000 Hz
#endif
#if SAMPLESPEED == 4000
//#define TMR0prescaler   RTCC_DIV_16                                             // 4010,70 Hz
//#define TMR0preload   69                                                       // 4010,70 Hz
#endif
#if SAMPLESPEED == 5000
//#define TMR0prescaler   RTCC_DIV_16                                             // 5000 Hz
//#define TMR0preload   106                                                       // 5000 Hz
#endif
#if SAMPLESPEED == 6000
#define TMR0prescaler   RTCC_DIV_16                                             // 6000 Hz
#define TMR0preload   131                                                       // 6000 Hz
#endif
#if SAMPLESPEED == 7500
//#define TMR0prescaler   RTCC_DIV_32                                             // 7.500 Hz
//#define TMR0preload   206                                                       // 7.500 Hz
#endif
#if SAMPLESPEED == 10000
//#define TMR0prescaler   RTCC_DIV_8                                             // 10.000 Hz
//#define TMR0preload   106                                                       // 10.000 Hz
#endif

// Variables ///////////////////////////////////////////////////////////////////
//#byte timer0high = 0xfd7
#byte timer0low = 0xfd6                                                         //address of timer0 TMR0L register
int1 sampleAvailable = FALSE;
int16 adcValue = 0;
int16 baseAdcValue = 0;
int1 startCapture = FALSE;

// Interrupt routines //////////////////////////////////////////////////////////
#int_RTCC
void RTCC_isr(void) {
   adcValue = read_adc();                                                       //read new sample from load cell through the adc
   timer0low = timer0low + TMR0preload;                                         //set timer0 count register with correction value (for timer accuracy)
   sampleAvailable = TRUE;                                                      //signal state machine that a new adc sample is available
}

// Functions ///////////////////////////////////////////////////////////////////
void Initialize(void) {
   setup_timer_0(RTCC_INTERNAL | RTCC_8_BIT | TMR0prescaler);

   //initialize ADC
   setup_adc_ports( AN0_ANALOG );
   setup_adc( ADC_CLOCK_INTERNAL );
   set_adc_channel( 0 );

   //initialize USB
   usb_cdc_init();
   usb_init();
}


// Main ////////////////////////////////////////////////////////////////////////
void main() {
   int8 i;

   Initialize();
   delay_ms(100);

   while(!usb_cdc_connected()) {                                                //flash LED until serial software connects
      output_toggle(LED1);
      delay_ms(50);
   }
   output_low(LED1);

   printf(usb_cdc_putc, "\r\n\r\nLoad Cell ADC (c)2008 www.steeman.be\r\n");
   printf(usb_cdc_putc, "--------------------------------------------------------------\r\n", baseAdcValue);
   printf(usb_cdc_putc, "!!!!! Waiting for ignition, switch on text capture now !!!!!\r\n\r\n");

   for (i=0; i<100; i++) {
      baseAdcValue += read_adc();                                               //take avg samples to set adc base value
   }
   baseAdcValue /= 100;

   enable_interrupts( INT_TIMER0 );
   enable_interrupts( GLOBAL );

   do {
      usb_task();
      if (usb_enumerated()) {
         if (sampleAvailable) {                                                 //if new timer0 has executed ISR and read ADC
            if ( (adcValue > baseAdcValue + 3) && (!startCapture) ) {           //if sample jumps 3 adc bits over the base value,
               startCapture = TRUE;                                             //then the test has started
               printf(usb_cdc_putc, "Sample speed: %ld Hz - Base value: %ld ADC bits\r\n", SAMPLESPEED, baseAdcValue);
            }
            if (startCapture)                                                   //if test has started
               printf(usb_cdc_putc, "%ld\r\n", adcValue);                       //start outputting sample values to usb
            sampleAvailable = FALSE;                                            //clear value for next ISR pass
         }
      }
   } while (TRUE);
}

