| 277 |
Kevin |
1 |
#include "defines.h"
|
|
|
2 |
#include "CPS.h"
|
|
|
3 |
|
|
|
4 |
static CPS_DATA *cps_data_p;
|
|
|
5 |
|
|
|
6 |
void CPS_Init(CPS_DATA* data) {
|
|
|
7 |
cps_data_p = data;
|
|
|
8 |
for (uint8_t i = 0; i < 4; i++) {
|
|
|
9 |
cps_data_p->btn_pressed[i] = 0;
|
|
|
10 |
cps_data_p->btn_last_value[i] = 0;
|
|
|
11 |
cps_data_p->btn_avg_value[i] = 0;
|
|
|
12 |
cps_data_p->btn_pct_value[i] = 0;
|
|
|
13 |
}
|
|
|
14 |
|
|
|
15 |
cps_data_p->channels[0] = 8;
|
|
|
16 |
cps_data_p->channels[1] = 9;
|
|
|
17 |
|
|
|
18 |
/* Initialize FVR for the upper threshold (Ref+) */
|
|
|
19 |
FVRCONbits.CDAFVR = 0b01; // Gain of 1x (1.024V)
|
|
|
20 |
FVRCONbits.FVREN = 1; // Enable FVR module
|
|
|
21 |
|
|
|
22 |
/* Initialize DAC for the lower threshold (Ref-) to Vss */
|
|
|
23 |
DACCON0bits.DACEN = 0; // Disable DAC
|
|
|
24 |
DACCON0bits.DACLPS = 0; // Negative reference source selected
|
|
|
25 |
DACCON0bits.DACOE = 0; // Output not routed to DACOUT pin
|
|
|
26 |
DACCON0bits.DACPSS = 0b00; // Vss used as positive source
|
|
|
27 |
// DACCON0bits.DACNSS = 0; // Vss used as negative source
|
|
|
28 |
// Output voltage formula:
|
|
|
29 |
// V_out = ((V_source+ - V_source-) * (DACR / 32)) + V_source-
|
|
|
30 |
DACCON1bits.DACR = 0b00000; // Voltage output set to 0v
|
|
|
31 |
|
|
|
32 |
// /* Initialize DAC for the lower threshold (Ref-) to variable setting */
|
|
|
33 |
// DACCON0bits.DACEN = 1; // Enable DAC
|
|
|
34 |
// DACCON0bits.DACLPS = 1; // Positive reference source selected
|
|
|
35 |
// DACCON0bits.DACOE = 0; // Output not routed to DACOUT pin
|
|
|
36 |
// DACCON0bits.DACPSS = 0b10; // FVR buffer2 used as positive source
|
|
|
37 |
//// DACCON0bits.DACNSS = 0; // Vss used as negative source
|
|
|
38 |
// // Output voltage formula:
|
|
|
39 |
// // V_out = ((V_source+ - V_source-) * (DACR / 32)) + V_source-
|
|
|
40 |
// DACCON1bits.DACR = 0b10000; // Voltage output set to 0.512v
|
|
|
41 |
|
|
|
42 |
/* Initialize Timer 0 */
|
|
|
43 |
OPTION_REGbits.TMR0CS = 0; // Clock source is FOSC/4
|
|
|
44 |
OPTION_REGbits.PSA = 0; // Prescaler enabled
|
|
|
45 |
OPTION_REGbits.PS = 0b110; // Prescaler of 1:128
|
|
|
46 |
|
|
|
47 |
/* Initialize Timer 1 */
|
|
|
48 |
T1CONbits.TMR1CS = 0b11; // Clock source is Capacitive Sensing Oscillator
|
|
|
49 |
T1CONbits.T1CKPS = 0b00; // 1:1 Prescale value
|
|
|
50 |
T1GCONbits.TMR1GE = 1; // Counting is controlled by the gate function
|
|
|
51 |
T1GCONbits.T1GPOL = 1; // Gate is active high
|
|
|
52 |
T1GCONbits.T1GTM = 1; // Gate toggle mode is enabled
|
|
|
53 |
T1GCONbits.T1GSPM = 0; // Gate single-pulse mode is disabled
|
|
|
54 |
T1GCONbits.T1GSS = 0b01; // Gate source is Timer 0 overflow
|
|
|
55 |
T1CONbits.TMR1ON = 1; // Enables timer 1
|
|
|
56 |
|
|
|
57 |
/* Initialize CPS Module */
|
|
|
58 |
CPSCON0bits.CPSRM = 1; // DAC and FVR used for Vref- and Vref+
|
|
|
59 |
CPSCON0bits.CPSRNG = 0b11; // Osc in high range (100uA)
|
|
|
60 |
CPSCON0bits.T0XCS = 0; // Timer 0 clock runs at FOSC/4
|
|
|
61 |
CPSCON1 = cps_data_p->channels[0];
|
|
|
62 |
cps_data_p->channel = 0;
|
|
|
63 |
CPSCON0bits.CPSON = 1; // CPS module is enabled
|
|
|
64 |
|
|
|
65 |
/* Initialize timer interrupts and clear timers */
|
|
|
66 |
INTCONbits.TMR0IE = 1; // Timer 0 interrupt enabled
|
|
|
67 |
PIE1bits.TMR1IE = 0; // Timer 1 interrupt disabled
|
|
|
68 |
CPS_Reset();
|
|
|
69 |
}
|
|
|
70 |
|
|
|
71 |
void CPS_Timer_0_Interrupt_Handler() {
|
|
|
72 |
uint16_t value = TMR1;
|
|
|
73 |
int32_t percent;
|
|
|
74 |
|
|
|
75 |
if (value < 10) {
|
|
|
76 |
return;
|
|
|
77 |
}
|
|
|
78 |
|
|
|
79 |
// Calculate percentage change
|
|
|
80 |
percent = (int32_t)cps_data_p->btn_avg_value[cps_data_p->channel]-(int32_t)value;
|
|
|
81 |
if (percent < 0)
|
|
|
82 |
percent = 0;
|
|
|
83 |
else {
|
|
|
84 |
percent *= 100;
|
|
|
85 |
percent /= cps_data_p->btn_avg_value[cps_data_p->channel];
|
|
|
86 |
}
|
|
|
87 |
|
|
|
88 |
cps_data_p->btn_last_value[cps_data_p->channel] = value;
|
|
|
89 |
cps_data_p->btn_pct_value[cps_data_p->channel] = percent;
|
|
|
90 |
|
|
|
91 |
if (percent < CPS_PCT_OFF) {
|
|
|
92 |
// Calculate average
|
|
|
93 |
cps_data_p->btn_avg_value[cps_data_p->channel] +=
|
|
|
94 |
// ((int32_t)value - (int32_t)cps_data_p->btn_avg_value[cps_data_p->channel])/CPS_AVG_COUNT;
|
|
|
95 |
((int32_t)value - (int32_t)cps_data_p->btn_avg_value[cps_data_p->channel]) >> 4;
|
|
|
96 |
|
|
|
97 |
// Set flag to indicate that button is not pressed
|
|
|
98 |
cps_data_p->btn_pressed[cps_data_p->channel] = 0;
|
|
|
99 |
} else if (percent > CPS_PCT_ON) {
|
|
|
100 |
// Set flag to indicate that button was pressed
|
|
|
101 |
cps_data_p->btn_pressed[cps_data_p->channel] = 1;
|
|
|
102 |
}
|
|
|
103 |
|
|
|
104 |
cps_data_p->channel = cps_data_p->channel + 1;
|
|
|
105 |
if (cps_data_p->channel == CPS_NUM_CHANNELS)
|
|
|
106 |
cps_data_p->channel = 0;
|
|
|
107 |
|
|
|
108 |
CPSCON1 = cps_data_p->channels[cps_data_p->channel];
|
|
|
109 |
|
|
|
110 |
CPS_Reset();
|
|
|
111 |
}
|
|
|
112 |
|
|
|
113 |
void CPS_Reset() {
|
|
|
114 |
TMR1 = 0;
|
|
|
115 |
TMR0 = 0;
|
|
|
116 |
}
|
|
|
117 |
|
|
|
118 |
void CPS_Enable() {
|
|
|
119 |
INTCONbits.TMR0IE = 1; // Timer 0 interrupt enabled
|
|
|
120 |
T1CONbits.TMR1ON = 1;
|
|
|
121 |
CPSCON0bits.CPSON = 1;
|
|
|
122 |
CPS_Reset();
|
|
|
123 |
}
|
|
|
124 |
|
|
|
125 |
void CPS_Disable() {
|
|
|
126 |
INTCONbits.TMR0IE = 0;
|
|
|
127 |
CPSCON0bits.CPSON = 0;
|
|
|
128 |
T1CONbits.TMR1ON = 0;
|
|
|
129 |
}
|