uint readpins(int PinNum) { uint avalue; while(!IFS0bits.AD1IF); // wait until buffers contain new samples //AD1CON1bits.ASAM = 0; // stop automatic sampling (essentially shut down ADC in this mode) if(ReadActiveBufferADC10() == 1)// check which buffers are being written to and read from the other set { switch(PinNum) { case 0: avalue = ADC1BUF0; break; case 1: avalue = ADC1BUF1; break; case 2: avalue = ADC1BUF2; break; } } else { switch(PinNum) { case 0: avalue = ADC1BUF8; break; case 1: avalue = ADC1BUF9; break; case 2: avalue = ADC1BUFA; break; } } //AD1CON1bits.ASAM = 1; // restart automatic sampling mAD1ClearIntFlag(); // clear ADC interrupt flag return avalue; }
/* Timer ISR callback function for CVD measurements. Requires external pull-up resistors to Vdd for all buttons. For use on devices that don't support TimerCallbackFunc1 or have a CTMU (TimerCallbackFunc4). */ void TimerCallbackFunc2(void) { UINT16 Vpos, Vneg, Vmeas, Vupdate; UINT16 iChan, iChanBit; UINT16 iRefChan, iRefBit; iRefChan = REF_CHANNEL; iRefBit = 1<<iRefChan; iChan = ScanChannels[button_set_number]; iChanBit = 1<<iChan; //***************************************************************************** // Measure Vneg //***************************************************************************** #if defined( TICKLE_LED1 ) LATFSET = 1<<0; // Use pin 5 on J2 (RF0) #endif// defined( TICKLE_LED1 ) asm("di"); // disable interrupts AD1CON1bits.SAMP = 1; //Start Chold charging Process ChargeDelay(); LATBCLR = iRefBit; //Ref pin now low ChargeDelay(); AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin ChargeDelay(); //Wait as ADC SAH cap discharges and sensor cap charges TRISBSET = iChanBit; //Tri-state sensor port LATBCLR = iChanBit; //Sensor port low #if defined(CHARGE_DISCHARGE_CYCLE_1) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH charges AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin ChargeDelay(); //Wait as ADC SAH discharges #endif//defined(CHARGE_DISCHARGE_CYCLE_1) #if defined(CHARGE_DISCHARGE_CYCLE_2) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH charges AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin ChargeDelay(); //Wait as ADC SAH discharges #endif//defined(CHARGE_DISCHARGE_CYCLE_2) #if defined(CHARGE_DISCHARGE_CYCLE_3) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH charges AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin ChargeDelay(); //Wait as ADC SAH discharges #endif//defined(CHARGE_DISCHARGE_CYCLE_3) #if defined(CHARGE_DISCHARGE_CYCLE_4) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH charges AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin ChargeDelay(); //Wait as ADC SAH discharges #endif//defined(CHARGE_DISCHARGE_CYCLE_4) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH charges AD1CON1bits.SAMP = 0; //Start A/D conversion #if defined( TICKLE_LED1 ) LATFCLR = 1<<0; // Use pin 5 on J2 (RF0) #endif// defined( TICKLE_LED1 ) asm("ei"); //re-enable interrupts //Capture Voltage while ( !AD1CON1bits.DONE ) //Wait for ADC conversion complete { // Do Nothing } AD1CON1bits.DONE = 0; Vneg = ReadADC10(ReadActiveBufferADC10())<<5; //Read new Vneg //***************************************************************************** // Measure Vpos //***************************************************************************** //Be sure ADC is in known state TRISBCLR = iRefBit; //Make ref pin output AD1CHSbits.CH0SA = iRefChan; //Switch ADC to ref pin AD1CON1bits.SAMP = 1; //Start Chold charging Process ChargeDelay(); #if defined( TICKLE_LED1 ) LATFSET = 1<<0; // Use pin 5 on J2 (RF0) #endif// defined( TICKLE_LED1 ) asm("di"); // disable interrupts //Setup: SAH cap high, sensor cap low LATBCLR = iChanBit; //Sensor pin low TRISBCLR = iChanBit; //Clear tri-state on sensor pin //Charging the ADC's sample and hold (SAH) capacitor LATBSET = iRefBit; //Make ref pin high TRISBCLR = iRefBit; //Make ref pin output #if defined( CHARGE_DISCHARGE_CYCLE_1 ) AD1CHSbits.CH0SA = iRefChan; //Switch ADC to ref pin ChargeDelay(); //Wait as ADC SAH cap charges TRISBSET = iChanBit; //Tristate sensor pad (make it input) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH cap discharges to sensor cap #endif//defined( CHARGE_DISCHARGE_CYCLE_1 ) #if defined( CHARGE_DISCHARGE_CYCLE_2 ) AD1CHSbits.CH0SA = iRefChan; //Switch ADC to ref pin ChargeDelay(); //Wait as ADC SAH cap charges AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH cap discharges to sensor cap #endif//defined( CHARGE_DISCHARGE_CYCLE_2 ) #if defined( CHARGE_DISCHARGE_CYCLE_3 ) AD1CHSbits.CH0SA = iRefChan; //Switch ADC to ref pin ChargeDelay(); //Wait as ADC SAH cap charges AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH cap discharges to sensor cap #endif//defined( CHARGE_DISCHARGE_CYCLE_3 ) #if defined( CHARGE_DISCHARGE_CYCLE_4 ) AD1CHSbits.CH0SA = iRefChan; //Switch ADC to ref pin ChargeDelay(); //Wait as ADC SAH cap charges AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH cap discharges to sensor cap #endif//defined( CHARGE_DISCHARGE_CYCLE_4 ) //Capture Voltage AD1CON1bits.SAMP = 0; //Start A/D conversion #if defined( TICKLE_LED1 ) LATFCLR = 1<<0; // Use pin 5 on J2 (RF0) #endif// defined( TICKLE_LED1 ) asm("ei"); //re-enable interrupts while ( !AD1CON1bits.DONE ) //Wait for ADC conversion complete { //Do Nothing } AD1CON1bits.DONE = 0; Vpos = ReadADC10(ReadActiveBufferADC10())<<5; //Read new Vpos #if defined(USE_DIFFERENTIAL_MEASUREMENTS) Vmeas = Vpos + 32768 - Vneg; //Calculate new Vmeas #else //single ended Vmeas = Vpos; //Single ended measurements #endif //defined USE_DIFFERENTIAL_MEASUREMENTS #if defined(LIMIT_SLEW_RATE) if ( IgnoreCurrentDataFlag == TRUE ) { Vpos = Vneg = 0; Vmeas = OldRawData[button_set_number]; } # if defined(USE_DIFFERENTIAL_MEASUREMENTS) # define VMEAS_DELTA (1<<(5)) # else # define VMEAS_DELTA (1<<(6)) # endif//defined(USE_DIFFERENTIAL_MEASUREMENTS) if (Vmeas > OldRawData[button_set_number]) { OldRawData[button_set_number] += VMEAS_DELTA; } else if(Vmeas < OldRawData[button_set_number]) { OldRawData[button_set_number] -= VMEAS_DELTA; } Vupdate = OldRawData[button_set_number]; #else if ( IgnoreCurrentDataFlag == TRUE ) { Vmeas = Vpos = Vneg = 0; Vupdate = OldRawData[button_set_number]; } else { OldRawData[button_set_number] = Vupdate = Vmeas; } #endif//defined(LIMIT_SLEW_RATE) ButtonCumulativeSum[button_set_number] += Vupdate; #if defined( UART_DUMP_RAW_COUNTS ) CurRawData[ HF_Read_Number ][button_set_number] = Vmeas; #elif defined( UART_DUMP_ALL_COUNTS ) CurRawData[3*HF_Read_Number+0][button_set_number] = Vpos; CurRawData[3*HF_Read_Number+1][button_set_number] = Vneg; CurRawData[3*HF_Read_Number+2][button_set_number] = Vmeas; #endif//defined( UART_DUMP_RAW_COUNTS ) //Measurement teardown LATBCLR = iChanBit; //Make sensor port low to discharge sensor pad //Next Measurement?? button_set_number++; //Increment the button number to move on to the next button if(button_set_number == NumberScanChannels) //if scanned all the buttons { HF_Read_Number++; //Start the next set of HF Scans button_set_number = 0; //Start over at the first button if ( HF_Read_Number < NUM_HF_READS ) // Not done with scans { EmTouchDataReady = FALSE; } else //All HF scans done, compute average, signal we're done { EmTouchDataReady = TRUE; // We're done with complete scan HF_Read_Number = 0; // Start next set of HF scans } } else { EmTouchDataReady = FALSE; } return; // we're done! }
/* This version of the callback function replaces the pull-up resistors used in TimerCallBackFunc2 with 10 to 30 charges from the ADC's sample and hold (SAH) capacitor. This improves noise performance at the cost of longer execution. */ void Timer4CallbackFunc3(void) { UINT16 Vpos, Vneg, Vmeas, Vupdate; UINT16 iChan, iChanBit; UINT16 iRefChan, iRefBit; iRefChan = REF_CHANNEL; iRefBit = 1<<iRefChan; iChan = ScanChannels[button_set_number]; iChanBit = 1<<iChan; //Mask shows which bits need changing to toggle between reference and sensor AD1CHS_Mask = (iRefChan<<16)^(iChan<<16); //XOR = bits that are different //***************************************************************************** // Measure Vpos //***************************************************************************** //Bring up ADC in known state AD1CON1bits.SAMP = 1; //Start Chold charging Process LATBCLR = iRefBit; //Ref pin now low TRISBCLR = iRefBit; //Make reference pin output AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin LATBSET = iRefBit; //Make reference pin high TRISBSET = iChanBit; //Tri-state sensor port LATBCLR = iChanBit; //Sensor port low //This charge/discharge cycle is necessary to start the process AD1CHSbits.CH0SA = iRefChan; //Charge ADC Sample and Hold capacitor TRISBSET = iChanBit; //Tri-state sensor port pin again AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button # if defined(CHARGE_DISCHARGE_CYCLE_2) AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button # endif//defined(CHARGE_DISCHARGE_CYCLE_2) # if defined(CHARGE_DISCHARGE_CYCLE_3) AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button # endif//defined(CHARGE_DISCHARGE_CYCLE_3) # if defined(CHARGE_DISCHARGE_CYCLE_3) AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button # endif//defined(CHARGE_DISCHARGE_CYCLE_4) AD1CON1bits.SAMP = 0; //Start ADC conversion //Wait for ADC conversion complete while ( !AD1CON1bits.DONE ) { //Do Nothing } AD1CON1bits.DONE = 0; Vpos = ReadADC10(ReadActiveBufferADC10())<<5; //ADC measurement //***************************************************************************** // Measure Vneg //***************************************************************************** #if !defined(USE_DIFFERENTIAL_MEASUREMENTS) # error('This file supports differential measurements only! Use mTouchCap_Timers.c instead.') #endif//!defined(USE_DIFFERENTIAL_MEASUREMENTS) AD1CON1bits.SAMP=1; //Enable sampling again // Repeat charging to bring button capacitor to near Vdd in voltage, using ADC #if defined(BUTTON_CHARGE_CYCLE_1) // Charge cycles 1 - 10 // Button charge #01 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #02 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #03 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #04 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #05 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #06 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #07 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #08 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #09 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #10 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button #endif//defined(BUTTON_CHARGE_CYCLE_1) #if defined(BUTTON_CHARGE_CYCLE_2) // Charge cycles 11 - 20 // Button Charge #11 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #12 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #13 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #14 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #15 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #16 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #17 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #18 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #19 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #20 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button #endif//defined(BUTTON_CHARGE_CYCLE_2) #if defined(BUTTON_CHARGE_CYCLE_3) // Charge cycles 21 - 30 // Button Charge #21 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #22 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #23 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #24 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #25 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #26 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #27 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #28 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #29 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #30 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button #endif//defined(BUTTON_CHARGE_CYCLE_3) #if defined(BUTTON_CHARGE_CYCLE_4) // Charge cycles 31 - 40 // Button Charge #31 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #32 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #33 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #34 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #35 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #36 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #37 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #38 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #39 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #40 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button #endif//defined(BUTTON_CHARGE_CYCLE_4) //Button cap is charged, now start dumping charge with ADC's SAH cap LATBCLR = iRefBit; //Make reference pin low # if defined(CHARGE_DISCHARGE_CYCLE_1) AD1CHSINV = AD1CHS_Mask; //Switch to reference to discharge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge SAH cap # endif//defined(CHARGE_DISCHARGE_CYCLE_1) # if defined(CHARGE_DISCHARGE_CYCLE_2) AD1CHSINV = AD1CHS_Mask; //Switch to reference to discharge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge SAH cap # endif//defined(CHARGE_DISCHARGE_CYCLE_2) # if defined(CHARGE_DISCHARGE_CYCLE_3) AD1CHSINV = AD1CHS_Mask; //Switch to reference to discharge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge SAH cap # endif//defined(CHARGE_DISCHARGE_CYCLE_3) # if defined(CHARGE_DISCHARGE_CYCLE_4) AD1CHSINV = AD1CHS_Mask; //Switch to reference to discharge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge SAH cap # endif//defined(CHARGE_DISCHARGE_CYCLE_4) AD1CON1bits.SAMP = 0; //Start ADC conversion //Wait for ADC conversion complete while ( !AD1CON1bits.DONE ) { // Do Nothing } AD1CON1bits.DONE = 0; TRISBCLR = iChanBit; //Remove tri-state on sensor port pin, make it output // Read new Vneg Vneg = ReadADC10(ReadActiveBufferADC10())<<5; // Calculate new Vmeas Vmeas = Vpos + 32768 - Vneg; #if defined(LIMIT_SLEW_RATE) # define VMEAS_DELTA (1<<(5)) if (Vmeas > OldRawData[button_set_number]) { OldRawData[button_set_number] += VMEAS_DELTA; } else if(Vmeas < OldRawData[button_set_number]) { OldRawData[button_set_number] -= VMEAS_DELTA; } Vupdate = OldRawData[button_set_number]; #else Vupdate = Vmeas; #endif//defined(LIMIT_SLEW_RATE) ButtonCumulativeSum[button_set_number] += Vupdate; #if defined( UART_DUMP_RAW_COUNTS ) CurRawData[ HF_Read_Number ][button_set_number] = Vmeas; #elif defined( UART_DUMP_ALL_COUNTS ) CurRawData[3*HF_Read_Number+0][button_set_number] = Vpos; CurRawData[3*HF_Read_Number+1][button_set_number] = Vneg; CurRawData[3*HF_Read_Number+2][button_set_number] = Vmeas; #endif//defined( UART_DUMP_RAW_COUNTS ) //Next Measurement?? button_set_number++; //Increment the button number to move on to the next button if(button_set_number == NumberScanChannels) //if scanned all the buttons { HF_Read_Number++; //Start the next set of HF Scans button_set_number = 0; //Start over at the first button if ( HF_Read_Number < NUM_HF_READS ) // Not done with scans { dataReadyCVD = FALSE; } else //All HF scans done, compute average, signal we're done { dataReadyCVD = TRUE; // We're done with complete scan HF_Read_Number = 0; // Start next set of HF scans } } else { dataReadyCVD = FALSE; } return; // we're done! }