/*********************************************
*	Author: Chris @ PyroElectro.com
*
*	Description: This firmware is made for the
*   PIC 18F452 microcontroller and it is ment to
*   be paired with two trimpot inputs on PORTA
*   AN0, AN1 and to send output signals out of
*   PORTD on RD0~RD3 to a motor controller IC,
*   the SN754410.
*
*	Date: March 31st, 2011
*
*	For Full Details On This Firmware Please
*	Visit: http://www.pyroelectro.com/tutorials/sn754410_dual_motor_control/
*********************************************/

#include <p18f452.h>
#include <adc.h>

void InterruptHandlerHigh (void);
void InterruptHandlerLow (void);

unsigned int ad_val_0 = 0;
unsigned int ad_val_1 = 0;
unsigned int ad_ready = 0;
unsigned char ad_chan = ADC_CH0;
unsigned int cnt = 0;

void main(void){

TRISA = 0xFF;
TRISC = 0x00;
TRISD = 0x00;
PORTC = 0x00;
PORTD = 0x00;

				//Setup Interrupts
RCON = 0b00000000; 
INTCON = 0b10000000;

OpenADC( ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_8ANA_0REF, ADC_CH0 & ADC_INT_ON );

ConvertADC();
while(1){
	if(ad_ready == 1){
			ConvertADC(); // Start conversion
			ad_ready = 0;	
		}	
	
/************** Control Motor #1 -BEGIN *******
***********************************************/
		//Go Forward
	if(ad_val_0>>3 > 63){
		if((ad_val_0>>3)-63 > cnt){
			PORTDbits.RD0 = 1;
			PORTDbits.RD1 = 0;
		}
		else{
			PORTDbits.RD0 = 0;
			PORTDbits.RD1 = 0;
		}
	}
		//Go Reverse
	else{
		if(63-(ad_val_0>>3) < cnt){
			PORTDbits.RD0 = 0;
			PORTDbits.RD1 = 0;
		}
		else{
			PORTDbits.RD0 = 0;
			PORTDbits.RD1 = 1;
		}
	}
/************** Control Motor #1 -END *********
***********************************************/

/************** Control Motor #2 - BEGIN ******
***********************************************/
		//Go Forward
	if(ad_val_1>>3 > 63){
		if((ad_val_1>>3)-63 > cnt){
			PORTDbits.RD2 = 1;
			PORTDbits.RD3 = 0;
		}
		else{
			PORTDbits.RD2 = 0;
			PORTDbits.RD3 = 0;
		}
	}
		//Go Reverse
	else{
		if(63-(ad_val_1>>3) < cnt){
			PORTDbits.RD2 = 0;
			PORTDbits.RD3 = 0;
		}
		else{
			PORTDbits.RD2 = 0;
			PORTDbits.RD3 = 1;
		}
	}

/************** Control Motor #2 -END *********
***********************************************/
	
	if(cnt == 128)
		cnt = 0;

	cnt++;
}

}


//**BEGIN INTERRUPT CONTROL**
#pragma code InterruptVectorHigh = 0x08		//interrupt pointer address (0x08 high priority)
void InterruptVectorHigh (void)
{
        _asm						//assembly code starts
        goto InterruptHandlerHigh	//interrupt control
        _endasm						//assembly code ends
}

#pragma code
#pragma interrupt InterruptHandlerHigh		//end interrupt control

#pragma code InterruptVectorLow = 0x18		//interrupt pointer address (0x18 low priority)
void InterruptVectorLow (void)
{
        _asm						//assembly code starts
        goto InterruptHandlerLow	//interrupt control
        _endasm						//assembly code ends
}

#pragma code
#pragma interrupt InterruptHandlerLow		//end interrupt control
//**END INTERRUPT CONTROL**


void InterruptHandlerHigh()		// Declaration of InterruptHandler
{	
		if(PIR1bits.ADIF == 1){
			PORTC = 0xFF;

			if(ad_chan == ADC_CH0){
				ad_val_0 = ReadADC();
				ad_ready = 1;
				ad_chan = ADC_CH1;
			}	
			else{
				ad_val_1 = ReadADC();
				ad_ready = 1;
				ad_chan = ADC_CH0;
			}
			SetChanADC(ad_chan);	
			PIR1bits.ADIF = 0;
		}
INTCONbits.GIEH = 1;						//Re-enable all interrupts
return;
}

void InterruptHandlerLow()	
{
//		if(PIR1bits.ADIF == 1){
//			ad_val = ReadADC();
//			ad_ready = 1;
//			PIR1bits.ADIF = 0;
//		}
INTCONbits.GIEL = 1;						//Re-enable all interrupts
return;
}