0,0 → 1,118 |
#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; |
} |