/****************************************************************************/
// 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 loopSize = 0;
int loopCount = 0;
#byte portB = 0x06
#byte portC = 0x07

/********************************** GLOBS ***********************************/

#INT_RTCC
rtccIsr()
{
    if ( !freqEnabled )
    {
        rtccTicks = 0;
        // stay in process commands 
        freqDuration = 0;
        return;
    }

    rtccTicks++;

    if ( FREQ_DURATION == rtccTicks )
    {
        rtccTicks = 0;
        ++freqDuration;
    }
}

void enable()
{
    freqEnabled = TRUE;
    printf("freq gen enabled\r\n");
    //portB = PORTB_LED_ON;
	return;
}

void disable()
{
    freqEnabled = FALSE;
    printf("freq gen disabled\r\n");
    //portB = PORTB_LED_OFF;
    return;
}

void processCmds()
{
    int b, c;
    static int old_b = 1;

    b = input(PIN_B0);
    //b = 0x00;

    if (b!=old_b && !b && !freqEnabled)
    {
		enable();
    }

    else if (b!=old_b && b && freqEnabled)
    {
		disable();
    }

    else if ( kbhit() )
    {
        c = getc();

        switch ( toupper(c))
        {
            case '1':   
            case 'a':   
            case 'A':   
                enable();
                break;
            case '2':   
            case 'b':   
            case 'B':   
                disable();
                break;
            default:    
                printf("1 - enable freq gen\r\n");
                printf("2 - disable freq gen\r\n");
                printf("? - help menu\r\n");
                break;
        }
    }
    old_b = b;
    return;
}

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 
    portC = 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();
        while ( freqDuration == 1 )
        processCmds();

		// Magnetic source output
        printf("Magnetic signal...\r\n");
        output_high(PIN_B1); //portB = PORTB_LED_ON;

        // 1000 Hz Magnetic
        while ( freqDuration == 2 )
        {
                   
            //50% duty cycle
            // off
            //portC = PORTC_1000HZ_FREQ;
            delay_us(124);
            // wave up 
            output_high(PIN_C0); //portC = PORTC_1000HZ_FREQ_UP;
            delay_us(247);
            // off
            output_low(PIN_C0); //portC = PORTC_1000HZ_FREQ;
            delay_us(247);
            // wave down 
            output_high(PIN_C1); //portC = PORTC_1000HZ_FREQ_DN;
            delay_us(247); // (5 us delay) 
            // off
            output_low(PIN_C1); //portC = PORTC_1000HZ_FREQ;
            delay_us(119);
        }
        
        /*
        // 100% Duty cycle
        for (loopCount = 0; loopCount < 250; ++loopCount)
        {
            // wave up 
            portC = PORTC_1000HZ_FREQ_UP;
            delay_us(499);
            // wave down 
            portC = PORTC_1000HZ_FREQ_DN;
            delay_us(494); // (5 us delay) 
        }
        // 50% Duty cycle
        for (loopCount = 0; loopCount < 250; ++loopCount)
        {
            // off
            portC = PORTC_1000HZ_FREQ;
            delay_us(124);
            // wave up 
            portC = PORTC_1000HZ_FREQ_UP;
            delay_us(249);
            // off
            portC = PORTC_1000HZ_FREQ;
            delay_us(249);
            // wave down 
            portC = PORTC_1000HZ_FREQ_DN;
            delay_us(249); // (5 us delay) 
            // off
            portC = PORTC_1000HZ_FREQ;
            delay_us(120);
        }
        // 25% Duty cycle
        for (loopCount = 0; loopCount < 250; ++loopCount)
        {
            // off
            portC = PORTC_1000HZ_FREQ;
            delay_us(187);
            // wave up 
            portC = PORTC_1000HZ_FREQ_UP;
            delay_us(124);
            // off
            portC = PORTC_1000HZ_FREQ;
            delay_us(374);
            // wave down 
            portC = PORTC_1000HZ_FREQ_DN;
            delay_us(124); // (5 us delay) 
            // off
            portC = PORTC_1000HZ_FREQ;
            delay_us(183);
        }
        // 10% Duty cycle
        for (loopCount = 0; loopCount < 250; ++loopCount)
        {
            // off
            portC = PORTC_1000HZ_FREQ;
            delay_us(224);
            // wave up 
            portC = PORTC_1000HZ_FREQ_UP;
            delay_us(49);
            // off
            portC = PORTC_1000HZ_FREQ;
            delay_us(449);
            // wave down 
            portC = PORTC_1000HZ_FREQ_DN;
            delay_us(49); // (5 us delay) 
            // off
            portC = PORTC_1000HZ_FREQ;
            delay_us(220);
        }
        */
        /*
        for (loopSize = 1; loopSize <= 141; ++loopSize) 
        {
            for (loopCount = 0; loopCount < loopSize; ++loopCount)
            {
                // wave up 
                portC = PORTC_1000HZ_FREQ_UP;
                delay_us(23);
            } // for (loopCount
            for (loopCount = 0; loopCount < loopSize; ++loopCount)
            {
                // wave down 
                portC = PORTC_1000HZ_FREQ_DN;
                delay_us(23); 
            } // for (loopCount
        } // for (loopSize
        */

        // 316 Hz Magnetic
        
        while ( freqDuration == 3 )
        {  
			// 75% duty cycle
            // off
            output_high(PIN_C5); //portC = PORTC_316HZ_FREQ;
            delay_us(193);
            // wave up 
            output_high(PIN_C0); //portC = PORTC_316HZ_FREQ_UP;
            delay_us(1160);
            // off
            output_low(PIN_C0); //portC = PORTC_316HZ_FREQ;
            delay_us(387);
            // wave down 
            output_high(PIN_C1); //portC = PORTC_316HZ_FREQ_DN;
            delay_us(1160); 
            // off
            output_low(PIN_C1); //portC = PORTC_316HZ_FREQ;
            delay_us(189);
        }
        
        /*
        // 100% Duty cycle
        for (loopCount = 0; loopCount < 79; ++loopCount)
        {
            // wave up 
            portC = PORTC_316HZ_FREQ_UP;
            delay_us(1580);
            // wave down 
            portC = PORTC_316HZ_FREQ_DN;
            delay_us(1575); // (5 us delay) 
        }
        // 75% Duty cycle
        for (loopCount = 0; loopCount < 79; ++loopCount)
        {
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(197);
            // wave up 
            portC = PORTC_316HZ_FREQ_UP;
            delay_us(1185);
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(394);
            // wave down 
            portC = PORTC_316HZ_FREQ_DN;
            delay_us(1185); // (5 us delay) 
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(193);
        }
        // 50% Duty cycle
        for (loopCount = 0; loopCount < 79; ++loopCount)
        {
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(394);
            // wave up 
            portC = PORTC_316HZ_FREQ_UP;
            delay_us(790);
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(790);
            // wave down 
            portC = PORTC_316HZ_FREQ_DN;
            delay_us(790); // (5 us delay) 
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(390);
        }
        // 25% Duty cycle
        for (loopCount = 0; loopCount < 79; ++loopCount)
        {
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(592);
            // wave up 
            portC = PORTC_316HZ_FREQ_UP;
            delay_us(394);
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(1185);
            // wave down 
            portC = PORTC_316HZ_FREQ_DN;
            delay_us(394); // (5 us delay) 
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(588);
        }
        // 10% Duty cycle
        for (loopCount = 0; loopCount < 79; ++loopCount)
        {
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(711);
            // wave up 
            portC = PORTC_316HZ_FREQ_UP;
            delay_us(157);
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(1422);
            // wave down 
            portC = PORTC_316HZ_FREQ_DN;
            delay_us(157); // (5 us delay) 
            // off
            portC = PORTC_316HZ_FREQ;
            delay_us(707);
        }
        */
        /*
        for (loopSize = 1; loopSize <= 141; ++loopSize) 
        {
            for (loopCount = 0; loopCount < loopSize; ++loopCount)
            {
                // wave up 
                portC = PORTC_316HZ_FREQ_UP;
                delay_us(23);
            } // for (loopCount
            for (loopCount = 0; loopCount < loopSize; ++loopCount)
            {
                // wave down 
                portC = PORTC_316HZ_FREQ_DN;
                delay_us(23); 
            } // for (loopCount
        } // for (loopSize
        */

        // 100 Hz Magnetic
        
        while ( freqDuration == 4 )
        {
            
            // 75% duty cycle
            // off
            output_high(PIN_C4); //portC = PORTC_100HZ_FREQ;
            delay_us(607);
            // wave up 
            output_high(PIN_C0); //portC = PORTC_100HZ_FREQ_UP;
            delay_us(3641);
            // off
            output_low(PIN_C0); //portC = PORTC_100HZ_FREQ;
            delay_us(1214);
            // wave down 
            output_high(PIN_C1); //portC = PORTC_100HZ_FREQ_DN;
            delay_us(3641); 
            // off
            output_low(PIN_C1); //portC = PORTC_100HZ_FREQ;
            delay_us(603);
        }
        
        /*
        // 100% Duty cycle
        for (loopCount = 0; loopCount < 25; ++loopCount)
        {
            // wave up 
            portC = PORTC_100HZ_FREQ_UP;
            delay_us(4999);
            // wave down 
            portC = PORTC_100HZ_FREQ_DN;
            delay_us(4995); // (5 us delay) 
        }
        // 75% Duty cycle
        for (loopCount = 0; loopCount < 25; ++loopCount)
        {
            // off
            portC = PORTC_100HZ_FREQ;
            delay_us(624);
            // wave up 
            portC = PORTC_100HZ_FREQ_UP;
            delay_us(3749);
            // off
            portC = PORTC_100HZ_FREQ;
            delay_us(1249);
            // wave down 
            portC = PORTC_100HZ_FREQ_DN;
            delay_us(3749); // (5 us delay) 
            // off
            portC = PORTC_100HZ_FREQ;
            delay_us(620);
        }
        // 50% Duty cycle
        for (loopCount = 0; loopCount < 25; ++loopCount)
        {
            // off
            portC = PORTC_100HZ_FREQ;
            delay_us(1249);
            // wave up 
            portC = PORTC_100HZ_FREQ_UP;
            delay_us(2499);
            // off
            portC = PORTC_100HZ_FREQ;
            delay_us(2499);
            // wave down 
            portC = PORTC_100HZ_FREQ_DN;
            delay_us(2499); // (5 us delay) 
            // off
            portC = PORTC_100HZ_FREQ;
            delay_us(1245);
        }
        // 25% Duty cycle
        for (loopCount = 0; loopCount < 25; ++loopCount)
        {
            // off
            portC = PORTC_100HZ_FREQ;
            delay_us(1874);
            // wave up 
            portC = PORTC_100HZ_FREQ_UP;
            delay_us(1249);
            // off
            portC = PORTC_100HZ_FREQ;
            delay_us(3749);
            // wave down 
            portC = PORTC_100HZ_FREQ_DN;
            delay_us(1249); 
            // off
            portC = PORTC_100HZ_FREQ;
            delay_us(1870);
        }
        */
        /*
        for (loopSize = 1; loopSize <= 160; ++loopSize) 
        {
            for (loopCount = 0; loopCount < loopSize; ++loopCount)
            {
                // wave up 
                portC = PORTC_100HZ_FREQ_UP;
                delay_us(23);
            } // for (loopCount
            for (loopCount = 0; loopCount < loopSize; ++loopCount)
            {
                // wave down 
                portC = PORTC_100HZ_FREQ_DN;
                delay_us(23); 
            } // for (loopCount
        } // for (loopSize
        */

        // wait for big caps to drain
        //portC = PORTC_DRAIN_CAPS;
        output_low(PIN_B1); //portB = PORTB_LED_OFF;
        delay_ms(50);

        // clear all the pins
        output_low(PIN_C5); 
		delay_ms(25);
        output_low(PIN_C4); //portC = PORTC_CLEAR_ALL;

        // wait for things to settle down 
        delay_ms(25);

        // process any queued cmds 
        while ( freqDuration == 5 )
        	processCmds();
        while ( freqDuration == 6 )
            processCmds();
        if(!freqEnabled)
            continue;

		// Current source output
        printf("Curent Source signal...\r\n");
        output_high(PIN_B1); //portB = PORTB_LED_ON;
        delay_ms(25);
        output_high(PIN_C2);
        // 1000 Hz Current
        while ( freqDuration == 7 )
        {
            // wave up
            output_high(PIN_C3); //portC = PORTC_CURRENT_ON;
            delay_us(490);
            // wave down 
            output_low(PIN_C3); //portC = PORTC_CURRENT_OFF;
            delay_us(480);
        }

        // 316 Hz Current
        while ( freqDuration == 8 )
        {
            // wave up 
            output_high(PIN_C3); //portC = PORTC_CURRENT_ON;
            delay_us(1540);
            // wave down 
            output_low(PIN_C3); //portC = PORTC_CURRENT_OFF;
            delay_us(1530); 
        }

        // 100 Hz Current
        while ( freqDuration == 9 )
        {
            // wave up 
            output_high(PIN_C3); //portC = PORTC_CURRENT_ON;
            delay_us(4990);
            // wave down 
            output_low(PIN_C3); //portC = PORTC_CURRENT_OFF;
            delay_us(4980);
        }

        // clear all the pins 
        output_low(PIN_C2); //portC = PORTC_CLEAR_ALL;
        delay_ms(25);
        output_low(PIN_B1); //portB = PORTB_LED_OFF;

        // wait for things to settle down 
        delay_ms(25);

        // do it again ! 
        freqDuration = 0;
    }
}
