/**********************************************************************
* ｩ 2005 Microchip Technology Inc.
*
* FileName:        adcDrv1.c
* Dependencies:    Header (.h) files if applicable, see below
* Processor:       dsPIC33Fxxxx
* Compiler:        MPLABｮ C30 v3.00 or higher
*
* SOFTWARE LICENSE AGREEMENT:
* Microchip Technology Incorporated ("Microchip") retains all ownership and 
* intellectual property rights in the code accompanying this message and in all 
* derivatives hereto.  You may use this code, and any derivatives created by 
* any person or entity by or on your behalf, exclusively with Microchip's
* proprietary products.  Your acceptance and/or use of this code constitutes 
* agreement to the terms and conditions of this notice.
*
* CODE ACCOMPANYING THIS MESSAGE IS SUPPLIED BY MICROCHIP "AS IS".  NO 
* WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED 
* TO, IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A 
* PARTICULAR PURPOSE APPLY TO THIS CODE, ITS INTERACTION WITH MICROCHIP'S 
* PRODUCTS, COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. 
*
* YOU ACKNOWLEDGE AND AGREE THAT, IN NO EVENT, SHALL MICROCHIP BE LIABLE, WHETHER 
* IN CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE OR BREACH OF STATUTORY DUTY), 
* STRICT LIABILITY, INDEMNITY, CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, SPECIAL, 
* PUNITIVE, EXEMPLARY, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, FOR COST OR EXPENSE OF 
* ANY KIND WHATSOEVER RELATED TO THE CODE, HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN 
* ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT 
* ALLOWABLE BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO 
* THIS CODE, SHALL NOT EXCEED THE PRICE YOU PAID DIRECTLY TO MICROCHIP SPECIFICALLY TO 
* HAVE THIS CODE DEVELOPED.
*
* You agree that you are solely responsible for testing the code and 
* determining its suitability.  Microchip has no obligation to modify, test, 
* certify, or support the code.
*
* REVISION HISTORY:
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Author            Date      Comments on this revision
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* N.Mochida         10/09/15  First release of source file
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* ADDITIONAL NOTES:
**********************************************************************/

#if defined(__dsPIC33F__)
#include "p33fxxxx.h"
#elif defined(__PIC24H__)
#include "p24hxxxx.h"
#endif

#include "adcdacDrv1.h"
#include "tglPin.h"
#include "dsp.h"

#define  SAMP_BUFF_SIZE	 	8	// Size of the input buffer per analog input
#define  NUM_CHS2SCAN		4	// Number of channels enabled for channel scan

extern	int indata1L;			//Lch Signal-in data
//extern	int indata2L;			//Lch MIC-in data
extern	int indata1R;			//Rch Signal-in data
//extern	int indata2R;			//Rch MIC-in data
extern	int outdata2L;			//Lch outdata //20100929 changed
extern	int outdata2R;			//Rch outdata //20100929 changed

//20100915 Add start
extern	int headtrack1;			//headtrack data
extern	int ext1;			//external data
//20100915 Add end

extern	int FLG;

extern	int DelayLineP1L[5];
extern	int DelayLineP1R[5];
extern	int DelayLineN1L[5];
extern	int DelayLineN1R[5];
extern	int DelayLineN2L[5];
extern	int DelayLineN2R[5];
extern	int CoeffP1[5];
extern	int CoeffN1[5];
extern	int CoeffN2[5];

extern	int OutWaveP1L;
extern	int OutWaveN1L;
extern	int OutWaveP1R;
extern	int OutWaveN1R;
extern	int OutWaveP2R;
extern	int OutWaveN2R;

/*=============================================================================
ADC INITIALIZATION FOR CHANNEL SCAN
=============================================================================*/
void initAdc1(void)
{

		AD1CON1bits.FORM   = 3;		// Data Output Format: Signed Fraction (Q15 format)
		AD1CON1bits.SSRC   = 2;		// Sample Clock Source: GP Timer starts conversion
		AD1CON1bits.ASAM   = 1;		// ADC Sample Control: Sampling begins immediately after conversion
		AD1CON1bits.AD12B  = 1;		// 12-bit ADC operation

		AD1CON2bits.CSCNA = 1;		// Scan Input Selections for CH0+ during Sample A bit
		AD1CON2bits.CHPS  = 0;		// Converts CH0

		AD1CON3bits.ADRC = 0;		// ADC Clock is derived from Systems Clock
//		AD1CON3bits.ADCS = 3;		// ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*4 = 100ns
						// ADC Conversion Time for 12-bit Tc=14*Tad = 1.4us
		AD1CON3bits.ADCS = 9;		// ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/20M)*10 = 500ns

		AD1CON2bits.SMPI    = (NUM_CHS2SCAN-1);	// 4 ADC Channel is scanned

		//AD1CSSH/AD1CSSL: A/D Input Scan Selection Register
//		AD1CSSH = 0x0000;			
		AD1CSSLbits.CSS0=1;		// Enable AN0 for channel scan
		AD1CSSLbits.CSS1=1;		// Enable AN1 for channel scan
		AD1CSSLbits.CSS2=1;		// Enable AN2 for channel scan
		AD1CSSLbits.CSS3=1;		// Enable AN3 for channel scan
 
 		//AD1PCFGH/AD1PCFGL: Port Configuration Register
		AD1PCFGL=0xFFFF;
//		AD1PCFGH=0xFFFF;
		AD1PCFGLbits.PCFG0 = 0;		// AN0 as Analog Input
		AD1PCFGLbits.PCFG1 = 0;		// AN1 as Analog Input 
 		AD1PCFGLbits.PCFG2 = 0;		// AN2 as Analog Input
		AD1PCFGLbits.PCFG3 = 0;		// AN3 as Analog Input 
	
        
        IFS0bits.AD1IF = 0;			// Clear the A/D interrupt flag bit
        IEC0bits.AD1IE = 1;			// Enable A/D interrupt 
        AD1CON1bits.ADON = 1;		// Turn on the A/D converter	

        tglPinInit();

}

/*=============================================================================
initDac() is used to configure D/A. 
=============================================================================*/
void initDac1(void)
{
	/* Initiate DAC Clock */
	ACLKCONbits.SELACLK = 0;	// FRC w/ Pll as Clock Source 
	ACLKCONbits.AOSCMD = 0;		// Auxiliary Oscillator Disabled
	ACLKCONbits.ASRCSEL = 0;	// Auxiliary Oscillator is the Clock Source
	ACLKCONbits.APSTSCLR = 7;	// FRC divide by 1 

	DAC1STATbits.ROEN = 1;		// Right Channel DAC Output Enabled  
	DAC1STATbits.LOEN = 1;		// Left Channel DAC Output Enabled  

	DAC1DFLT = 0x8000;		// DAC Default value is the midpoint 
	
				// 103.16KHz  	// 8.038KHz	// 44.211KHz	// 25KHz
//	DAC1CONbits.DACFDIV = 5; 	//76; 		//13; 		// 23; // Divide High Speed Clock by DACFDIV+1 
	DAC1CONbits.DACFDIV = 2;

	DAC1CONbits.FORM = 1;		// Data Format is signed integer
	DAC1CONbits.AMPON = 0;		// Analog Output Amplifier is enabled during Sleep Mode/Stop-in Idle mode

	DAC1CONbits.DACEN = 1;		// DAC1 Module Enabled 
}

/*=============================================================================  
Timer 3 is setup to time-out every 125 microseconds (8Khz Rate). As a result, the module 
will stop sampling and trigger a conversion on every Timer3 time-out, i.e., Ts=125us. 
=============================================================================*/
void initTmr3() 
{
        TMR3 = 0x0000;
        PR3 = 171;			//28.8kHz*4=115.2kHz
        IFS0bits.T3IF = 0;
        IEC0bits.T3IE = 0;

        //Start Timer 3
        T3CONbits.TON = 1;

}

/*=============================================================================  
ADC INTERRUPT SERVICE ROUTINE
=============================================================================*/
//int  ain3Buff[SAMP_BUFF_SIZE];
//int  ain4Buff[SAMP_BUFF_SIZE];
//int  ain10Buff[SAMP_BUFF_SIZE];
//int  ain13Buff[SAMP_BUFF_SIZE];

int  scanCounter=0;
int  sampleCounter=0;

//20100929 change start
void PushDelayP1L(int din1, int dout1) {  	// 遅延器のプッシュ（2次IIR）Lch PeakFilter
//Push Lch
	DelayLineP1L[4] = DelayLineP1L[3]; 	// b2 <- b1
	DelayLineP1L[3] = dout1; 		// b1 <- dout
	DelayLineP1L[2] = DelayLineP1L[1];	// a2 <- a1
	DelayLineP1L[1] = DelayLineP1L[0]; 	// a1 <- a0
	DelayLineP1L[0] = din1; 		// a0 <- din
}

void PushDelayP1R(int din2, int dout2) {  	// 遅延器のプッシュ（2次IIR）Rch PeakFilter
//Push Rch
	DelayLineP1R[4] = DelayLineP1R[3]; 	// b2 <- b1
	DelayLineP1R[3] = dout2; 		// b1 <- dout
	DelayLineP1R[2] = DelayLineP1R[1]; 	// a2 <- a1
	DelayLineP1R[1] = DelayLineP1R[0]; 	// a1 <- a0
	DelayLineP1R[0] = din2; // a0 <- din
}

void PushDelayN1L(int din1, int dout1) {  	// 遅延器のプッシュ（2次IIR）Lch Notch1Filter
//Push Lch
	DelayLineN1L[4] = DelayLineN1L[3]; 	// b2 <- b1
	DelayLineN1L[3] = dout1; 		// b1 <- dout
	DelayLineN1L[2] = DelayLineN1L[1];	// a2 <- a1
	DelayLineN1L[1] = DelayLineN1L[0]; 	// a1 <- a0
	DelayLineN1L[0] = din1; 		// a0 <- din
}

void PushDelayN1R(int din2, int dout2) {  	// 遅延器のプッシュ（2次IIR）Rch Notch1Filter
//Push Rch
	DelayLineN1R[4] = DelayLineN1R[3]; 	// b2 <- b1
	DelayLineN1R[3] = dout2; 		// b1 <- dout
	DelayLineN1R[2] = DelayLineN1R[1]; 	// a2 <- a1
	DelayLineN1R[1] = DelayLineN1R[0]; 	// a1 <- a0
	DelayLineN1R[0] = din2; // a0 <- din
}

void PushDelayN2L(int din1, int dout1) {  	// 遅延器のプッシュ（2次IIR）Lch NotchFilter
//Push Lch
	DelayLineN2L[4] = DelayLineN2L[3]; 	// b2 <- b1
	DelayLineN2L[3] = dout1; 		// b1 <- dout
	DelayLineN2L[2] = DelayLineN2L[1];	// a2 <- a1
	DelayLineN2L[1] = DelayLineN2L[0]; 	// a1 <- a0
	DelayLineN2L[0] = din1; 		// a0 <- din
}

void PushDelayN2R(int din2, int dout2) {  	// 遅延器のプッシュ（2次IIR）Rch NotchFilter
//Push Rch
	DelayLineN2R[4] = DelayLineN2R[3]; 	// b2 <- b1
	DelayLineN2R[3] = dout2; 		// b1 <- dout
	DelayLineN2R[2] = DelayLineN2R[1]; 	// a2 <- a1
	DelayLineN2R[1] = DelayLineN2R[0]; 	// a1 <- a0
	DelayLineN2R[0] = din2; 		// a0 <- din
}

int CalOutWaveP1L() { // デジタルフィルタの出力を計算 Peak1 Lch
	int tmp;

	tmp = VectorDotProduct(5, DelayLineP1L, CoeffP1); // データと係数積和演算（DSPライブラリ使用）
	tmp = tmp << 1;		//20101007 add

	return tmp;
}

int CalOutWaveP1R() { // デジタルフィルタの出力を計算 Peak1 Rch
	int tmp;

	tmp = VectorDotProduct(5, DelayLineP1R, CoeffP1); // データと係数積和演算（DSPライブラリ使用）
	tmp = tmp << 1;		//20101007 add

	return tmp;
}

int CalOutWaveN1L() { // デジタルフィルタの出力を計算 Notch1 Lch
	int tmp;

	tmp = VectorDotProduct(5, DelayLineN1L, CoeffN1); // データと係数積和演算（DSPライブラリ使用）
//	tmp = tmp << 1;

	return tmp;
}

int CalOutWaveN1R() { // デジタルフィルタの出力を計算 Notch1 Rch
	int tmp;		//

	tmp = VectorDotProduct(5, DelayLineN1R, CoeffN1); // データと係数積和演算（DSPライブラリ使用) 
//	tmp = tmp << 1;		//

	return tmp;		//
}

int CalOutWaveN2L() { // デジタルフィルタの出力を計算 Notch2 Lch
	int tmp;

	tmp = VectorDotProduct(5, DelayLineN2L, CoeffN2); // データと係数積和演算（DSPライブラリ使用）
	tmp = tmp << 1;

	return tmp;
}

int CalOutWaveN2R() { // デジタルフィルタの出力を計算 Notch2 Rch
	int tmp;		//

	tmp = VectorDotProduct(5, DelayLineN2R, CoeffN2); // データと係数積和演算（DSPライブラリ使用) 
	tmp = tmp << 1;		//

	return tmp;		//
}

void __attribute__((interrupt, no_auto_psv)) _ADC1Interrupt(void)
{
	switch (scanCounter)
	{
		case 0:	
			indata1L=ADC1BUF0; 		//20100915 changed
			break;

		case 1:
			indata1R=ADC1BUF0;  		//20100915 changed
			break;

		case 2:
			headtrack1= ADC1BUF0 ^ 0x8000; 	//20100915 changed 20100922 changed Not b15
			break;
	
		case 3:
			ext1 = ADC1BUF0 ^ 0x8000;   		//20100915 changed //20101004 change
			FLG = 1;
			break;
			
		default:
			break;			
			
	}

	DAC1LDAT = outdata2L; 				//20100915 changed //20100929 changed
	DAC1RDAT = outdata2R; 				//20100915 changed //20100929 changed
	scanCounter++;
	if(scanCounter==NUM_CHS2SCAN)	{
		scanCounter=0;
		sampleCounter++;
	}

	if(sampleCounter==SAMP_BUFF_SIZE)
		sampleCounter=0;

	tglPin();				// Toggle RA6
    IFS0bits.AD1IF = 0;		// Clear the ADC1 Interrupt Flag

}

