Subversion Repositories Code-Repo

Rev

Rev 277 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
}