/****************************************************************************/
// Copyright 2004 MBARI.                                                    
// Monterey Bay Aquarium Research Institute Proprietary Information.        
// All rights reserved.                                                     
/****************************************************************************/
#if defined(__PCM__)
#include <16f873.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=3580000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use fast_io(C)
#endif

#include <stdlib.h>
#include <string.h>
#include "freq_gen.h"

/********************************** GLOBS ***********************************/

long rtccTicks = 0;
int freqDuration = 0;
int freqEnabled = FALSE;
int magneticEnabled = TRUE;
int currentEnabled = TRUE;
char enabled[] = "enabled";
char disabled[] = "disabled";

/********************************** GLOBS ***********************************/

#INT_RTCC
rtccIsr()
{
    if ( !freqEnabled )
    {
        rtccTicks = 0;
        // stay in process commands 
        freqDuration = 0;
        return;
    }

    rtccTicks++;

    if ( FREQ_DURATION == rtccTicks )
    {
        rtccTicks = 0;
        ++freqDuration;
    }
}

void processCmds()
{
    int b, c;
    static int old_b = 1;

    b = input(PIN_B0);
    //b = 0x00;

    if (b!=old_b && !b && !freqEnabled)
    {
		freqEnabled = TRUE;
    }

    else if (b!=old_b && b && freqEnabled)
    {
		freqEnabled = FALSE;
    }

    if (b!=old_b || kbhit() )
    {
        if(b==old_b)        
        {
            c = getc();
	        switch (c)
	        {
	            case '1':   
	                freqEnabled = TRUE;
	                break;
	            case '2':   
	                freqEnabled = FALSE;
	                break;
	            case 'm':   
	                magneticEnabled = TRUE;
	                break;
	            case 'M':   
	                magneticEnabled = FALSE;
	                break;
	            case 'c':   
	                currentEnabled = TRUE;
	                break;
	            case 'C':   
	                currentEnabled = FALSE;
	                break;
	        }
	        printf("\r\nFreqGen %s\r\n",freqEnabled?enabled:disabled);
	        printf("Magnetic %s\r\n",magneticEnabled?enabled:disabled);
	        printf("Current %s\r\n",currentEnabled?enabled:disabled);
	        printf("1 - enable freq gen\r\n");
	        printf("2 - disable freq gen\r\n");
	        printf("m - enable magnetic\r\n");
	        printf("M - disable magnetic\r\n");
	        printf("c - enable current\r\n");
	        printf("C - disable current\r\n");
	        printf("? - help menu\r\n");
	    }
    }
    old_b = b;
    return;
}

#inline
void magnetic1000()
{
    //50% duty cycle
    // off
    delay_us(124);
    // wave up 
    output_high(PIN_C0);
    delay_us(247);
    // off
    output_low(PIN_C0);
    delay_us(247);
    // wave down 
    output_high(PIN_C1);
    delay_us(247);
    // off
    output_low(PIN_C1);
    delay_us(119);
}

#inline
void magnetic316()
{
    // 75% duty cycle
    // off
    delay_us(193);
    // wave up 
    output_high(PIN_C0); 
    delay_us(1160);
    // off
    output_low(PIN_C0);
    delay_us(387);
    // wave down 
    output_high(PIN_C1); 
    delay_us(1160); 
    // off
    output_low(PIN_C1); 
    delay_us(189);
}

#inline
void magnetic100()
{
    // 75% duty cycle
    // off
    delay_us(607);
    // wave up 
    output_high(PIN_C0);
    delay_us(3641);
    // off
    output_low(PIN_C0); 
    delay_us(1214);
    // wave down 
    output_high(PIN_C1);
    delay_us(3641); 
    // off
    output_low(PIN_C1); 
    delay_us(603);
}

#inline
void current1000()
{
    // wave up
    output_high(PIN_C3); 
    delay_us(490);
    // wave down 
    output_low(PIN_C3); 
    delay_us(480);
}

#inline
void current316()
{
    // wave up 
    output_high(PIN_C3); 
    delay_us(1540);
    // wave down 
    output_low(PIN_C3); 
    delay_us(1530); 
}

#inline
void current100()
{
    // wave up 
    output_high(PIN_C3);
    delay_us(4990);
    // wave down 
    output_low(PIN_C3); 
    delay_us(4980);
}

main()
{
    // setup port b bit 0 as input, 1 as output 
    set_tris_b(0x02);

    // setup port c bits 0-6 as outputs, 7 as input 
    set_tris_c(0x80);

    // init freq pins 
    output_c(PORTC_CLEAR_ALL);

    // setup the system clock 
    setup_counters(RTCC_INTERNAL, RTCC_DIV_64);

    // make sure interrupts are enabled 
    enable_interrupts(INT_RTCC);
    enable_interrupts(GLOBAL);

    // welcome message 
    printf("Freq Gen version %d.%d\r\n",
            FREQ_GEN_VERSION, FREQ_GEN_SUB_VERSION);

    // main loop 
    for(;;)
    {
        // wait for things to settle down 
        delay_ms(50);

        // process any queued cmds 
        while ( freqDuration == 0 )
        processCmds();

        if(magneticEnabled)
        {
            // Magnetic source output
            printf("Magnetic signal...\r\n");

	        // Turn on Red LED
	        output_high(PIN_B1); 
	
	        // 1000 Hz Magnetic
	        while ( freqDuration == 1 )
				magnetic1000();                   
	     
		    // enable 7.5 uF capacitor
	    	output_high(PIN_C5); 
	
	        // 316 Hz Magnetic 
	        while ( freqDuration == 2 )
	            magnetic316();
	
		    // enable 60 uF capacitor
	        output_high(PIN_C4); 
	
	        // 100 Hz Magnetic      
	        while ( freqDuration == 3 )
				magnetic100();                   
	            
	        // Turn off Red LED
	        output_low(PIN_B1); 
	
	        // Wait for big capacitors to drain
	        delay_ms(50);
	
	        // Disable Capacitors
	        output_low(PIN_C5); 
			delay_ms(25);
	        output_low(PIN_C4); 
	
	        // wait for things to settle down 
	        delay_ms(25);
	    }

        // process any queued cmds 
        while ( freqDuration <= 4 )
        	processCmds();
        while ( freqDuration == 5 )
            processCmds();
        while ( freqDuration == 6 )
            processCmds();
        while ( freqDuration == 7 )
            processCmds();

        // reset if disabled
        if(!freqEnabled)
            continue;

        if(currentEnabled)
        {
			// Current source output
	        printf("Curent Source signal...\r\n");
	
	        // Turn on Red LED
	        output_high(PIN_B1); 
	        delay_ms(25);
	
	        // Turn on power to current loop
	        //output_high(PIN_C2);
	
	        // 1000 Hz Current
	        while ( freqDuration == 8 )
	            current1000();
	
	        // 316 Hz Current
	        while ( freqDuration == 9 )
	            current316();
	
	        // 100 Hz Current
	        while ( freqDuration == 10 )
	            current100();
	
	        // Turn off power to current loop
	        //output_low(PIN_C2); 
	        delay_ms(25);
	
	        // Turn off Red LED
	        output_low(PIN_B1); 
 
            // Wait for things to settle down 
            delay_ms(25);
	    }

        // process any queued cmds 
        while ( freqDuration <= 11 )
        	processCmds();

        // Do it again ! 
        freqDuration = 0;
    }
}
