Subversion Repositories Code-Repo

Rev

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

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