Blame | Last modification | View Log | RSS feed
#include <xc.h>
#include "defines.h"
#include "base_CPS.h"
static CPS_DATA *cps_data_p;
void CPS_Init(CPS_DATA* data) {
cps_data_p = data;
for (char i = 0; i < 4; i++) {
cps_data_p->btn_pressed[i] = 0;
cps_data_p->btn_last_value[i] = 0;
cps_data_p->btn_avg_value[i] = 0;
cps_data_p->btn_pct_value[i] = 0;
}
/* Initialize port direction */
CPS_0_TRIS = 1;
CPS_1_TRIS = 1;
/* Initialize FVR for the upper threshold (Ref+) */
FVRCONbits.CDAFVR = 0b01; // Gain of 1x (1.024V)
FVRCONbits.FVREN = 1; // Enable FVR module
/* Initialize DAC for the lower threshold (Ref-) */
DACCON0bits.DACEN = 0; // Disable DAC
DACCON0bits.DACLPS = 0; // Negative reference source selected
DACCON0bits.DACOE = 0; // Output not routed to DACOUT pin
DACCON0bits.DACPSS = 0b00; // Vdd used as positive source
// DACCON0bits.DACNSS = 0; // Vss used as negative source
DACCON1bits.DACR = 0b00000; // Voltage output set to 0
/* Initialize Timer 0 */
OPTION_REGbits.TMR0CS = 0; // Clock source is FOSC/4
OPTION_REGbits.PSA = 0; // Prescaler enabled
OPTION_REGbits.PS = 0b111; // Prescaler of 1:256
/* Initialize Timer 1 */
T1CONbits.TMR1CS = 0b11; // Clock source is Capacitive Sensing Oscillator
T1CONbits.T1CKPS = 0b00; // 1:1 Prescale value
T1GCONbits.TMR1GE = 1; // Counting is controlled by the gate function
T1GCONbits.T1GPOL = 1; // Gate is active high
T1GCONbits.T1GTM = 1; // Gate toggle mode is enabled
T1GCONbits.T1GSPM = 0; // Gate single-pulse mode is disabled
T1GCONbits.T1GSS = 0b01; // Gate source is Timer 0 overflow
T1CONbits.TMR1ON = 1; // Enables timer 1
/* Initialize CPS Module */
CPSCON0bits.CPSRM = 1; // DAC and FVR used for Vref- and Vref+
CPSCON0bits.CPSRNG = 0b11; // Osc in high range (100uA)
CPSCON0bits.T0XCS = 0; // Timer 0 clock runs at FOSC/4
CPSCON1bits.CPSCH = 0b00; // Channel 0 (CPS0)
cps_data_p->channel = 0;
CPSCON0bits.CPSON = 1; // CPS module is enabled
/* Initialize timer interrupts and clear timers */
INTCONbits.TMR0IE = 1; // Timer 0 interrupt enabled
PIE1bits.TMR1IE = 0; // Timer 1 interrupt disabled
CPS_Reset();
}
void CPS_Timer_0_Interrupt_Handler() {
unsigned int value = TMR1;
long percent;
if (value < 10) {
return;
}
// Calculate percentage change
percent = (long)cps_data_p->btn_avg_value[cps_data_p->channel]-(long)value;
if (percent < 0)
percent = 0;
else {
percent *= 100;
percent /= cps_data_p->btn_avg_value[cps_data_p->channel];
}
cps_data_p->btn_last_value[cps_data_p->channel] = value;
cps_data_p->btn_pct_value[cps_data_p->channel] = percent;
if (percent < CPS_PCT_OFF) {
// Calculate average
cps_data_p->btn_avg_value[cps_data_p->channel] =
cps_data_p->btn_avg_value[cps_data_p->channel] +
((long)value - (long)cps_data_p->btn_avg_value[cps_data_p->channel])
/CPS_AVG_COUNT;
// Set flag to indicate that button is not pressed
cps_data_p->btn_pressed[cps_data_p->channel] = 0;
} else if (percent > CPS_PCT_ON)
// Set flag to indicate that button was pressed
cps_data_p->btn_pressed[cps_data_p->channel] = 1;
cps_data_p->channel = cps_data_p->channel + 1;
if (cps_data_p->channel == CPS_NUM_CHANNELS)
cps_data_p->channel = 0;
CPSCON1bits.CPSCH = cps_data_p->channel;
CPS_Reset();
}
void CPS_Reset() {
TMR1 = 0;
TMR0 = 0;
}
void CPS_Enable() {
INTCONbits.TMR0IE = 1; // Timer 0 interrupt enabled
T1CONbits.TMR1ON = 1;
CPSCON0bits.CPSON = 1;
CPS_Reset();
}
void CPS_Disable() {
INTCONbits.TMR0IE = 0;
CPSCON0bits.CPSON = 0;
T1CONbits.TMR1ON = 0;
}