Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
1125 linlun 1
/**
2
 * ...
3
 *
1466 arune 4
 * @author  Linus Lundin, Anders Runeson
1125 linlun 5
 *
6
 * @date    2009-03-01
7
 */
8
 
9
/*-----------------------------------------------------------------------------
10
 * Includes
1138 linlun 11
 *---------------------------------------------------------------------------*/
1136 arune 12
 
1138 linlun 13
#include <config.h>
14
#if PCINT_NUM_PCINTS > 0
15
 
1125 linlun 16
#include <inttypes.h>
17
#include <avr/io.h>
18
#include <avr/interrupt.h>
19
 
20
#include <drivers/mcu/pcint.h>
21
 
22
/*-----------------------------------------------------------------------------
23
 * Globals
24
 *---------------------------------------------------------------------------*/
25
 
26
struct {
27
    uint8_t pcintBit;
1466 arune 28
    uint8_t pcintMask;
1136 arune 29
    uint8_t lastStatus;
1125 linlun 30
    pcintCallback_t callback;
31
} pcints[PCINT_NUM_PCINTS];
1138 linlun 32
 
1125 linlun 33
/*-----------------------------------------------------------------------------
34
 * Interrupt Service Routines
35
 *---------------------------------------------------------------------------*/
36
 
37
/*********************************************************************//**
38
Function: ISR(PCINT0_vect)
39
Purpose:  Executed when pin change on PCINT0.
40
Input:    -
41
Returns:  -
42
**************************************************************************/
43
ISR(PCINT0_vect) {
1138 linlun 44
    uint8_t p;
45
    uint8_t rPinB=PINB;
46
    uint8_t rPinC=PINC;
47
    uint8_t rPinD=PIND;
48
 
1125 linlun 49
    /* Check which pin that have had a change and call the callback.*/
1129 linlun 50
    //printf("I\n");
1125 linlun 51
    for (p = 0; p < PCINT_NUM_PCINTS; p++)
1138 linlun 52
    {
1136 arune 53
        if (pcints[p].pcintBit < 8) {
1466 arune 54
            if (pcints[p].lastStatus != (rPinB & pcints[p].pcintMask)) {
55
                pcints[p].lastStatus = (rPinB & pcints[p].pcintMask);
1136 arune 56
                pcints[p].callback(p, pcints[p].lastStatus);
1125 linlun 57
            }
58
        } else if (pcints[p].pcintBit < 16) {
1466 arune 59
            if (pcints[p].lastStatus != (rPinC & pcints[p].pcintMask)) {
60
                pcints[p].lastStatus = (rPinC & pcints[p].pcintMask);
1136 arune 61
                pcints[p].callback(p, pcints[p].lastStatus);
1125 linlun 62
            }
63
        } else if (pcints[p].pcintBit < 24) {
1466 arune 64
            if (pcints[p].lastStatus != (rPinD & pcints[p].pcintMask)) {
65
                pcints[p].lastStatus = (rPinD & pcints[p].pcintMask);
1136 arune 66
                pcints[p].callback(p, pcints[p].lastStatus);
1125 linlun 67
            }
1136 arune 68
        }
1138 linlun 69
    }
70
 
1125 linlun 71
} /* ISR(PCINT0_vect) */
72
 
73
 
74
/*********************************************************************//**
75
Function: ISR(PCINT1_vect)
76
Purpose:  Executed when pin change on PCINT1.
77
Input:    -
78
Returns:  -
79
**************************************************************************/
1202 arune 80
#if ((__GNUC__ == 4  && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ > 2)||(__GNUC__ == 4  && __GNUC_MINOR__ > 2)||__GNUC__ > 4)
1125 linlun 81
ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
1129 linlun 82
#else
83
ISR_ALIAS(PCINT1_vect, PCINT0_vect);
84
#endif
1125 linlun 85
/*********************************************************************//**
86
Function: ISR(PCINT0_vect)
87
Purpose:  Executed when pin change on PCINT2.
88
Input:    -
89
Returns:  -
90
**************************************************************************/
1202 arune 91
#if ((__GNUC__ == 4  && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ > 2)||(__GNUC__ == 4  && __GNUC_MINOR__ > 2)||__GNUC__ > 4)
1125 linlun 92
ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
1129 linlun 93
#else
94
ISR_ALIAS(PCINT2_vect, PCINT0_vect);
95
#endif
1125 linlun 96
/*-----------------------------------------------------------------------------
97
 * Public Functions
98
 *---------------------------------------------------------------------------*/
99
 
100
void Pcint_SetCallback(uint8_t pcint_id, uint8_t pcintBit, pcintCallback_t callback)
101
{
1129 linlun 102
    //printf("Test\n");
1125 linlun 103
    if (pcint_id<PCINT_NUM_PCINTS)
104
    {
105
        uint8_t sreg = SREG;
106
        cli();
107
 
1134 arune 108
        PCIFR=(1<<PCIF0|1<<PCIF1|1<<PCIF2); /* clear any pending interrupt before enabling interrupts */
1138 linlun 109
        PCICR|=(1<<PCIE0|1<<PCIE1|1<<PCIE2);    /* enable interrupt for PCINT0-2 */
1466 arune 110
 
1125 linlun 111
        pcints[pcint_id].pcintBit = pcintBit;
1466 arune 112
        pcints[pcint_id].pcintMask = 1<<pcints[pcint_id].pcintBit%8;
1136 arune 113
        pcints[pcint_id].lastStatus = 0;
1125 linlun 114
        if (callback != 0) {
115
            if (pcints[pcint_id].pcintBit < 8) {
1466 arune 116
                pcints[pcint_id].lastStatus = (PINB & pcints[pcint_id].pcintMask);
117
                PCMSK0 |= pcints[pcint_id].pcintMask;
1129 linlun 118
//printf("PCMSK %u\n", PCMSK0);
1125 linlun 119
            } else if (pcints[pcint_id].pcintBit < 16) {
1466 arune 120
                pcints[pcint_id].lastStatus = (PINC & pcints[pcint_id].pcintMask);
121
                PCMSK1 |= pcints[pcint_id].pcintMask;
1129 linlun 122
//printf("PCMSK1 %u\n", PCMSK1);
1125 linlun 123
            } else if (pcints[pcint_id].pcintBit < 24) {
1466 arune 124
                pcints[pcint_id].lastStatus = (PIND & pcints[pcint_id].pcintMask);
125
                PCMSK2 |= pcints[pcint_id].pcintMask;
1129 linlun 126
//printf("PCMSK2 %u\n", PCMSK2);
1125 linlun 127
            }
128
        } else { //turn off interupt
129
            if (pcints[pcint_id].pcintBit < 8) {
1466 arune 130
                PCMSK0 &= ~pcints[pcint_id].pcintMask;
1125 linlun 131
            } else if (pcints[pcint_id].pcintBit < 16) {
1466 arune 132
                PCMSK1 &= ~pcints[pcint_id].pcintMask;
1125 linlun 133
            } else if (pcints[pcint_id].pcintBit < 24) {
1466 arune 134
                PCMSK2 &= ~pcints[pcint_id].pcintMask;
1125 linlun 135
            }
1138 linlun 136
        }
137
 
1125 linlun 138
        pcints[pcint_id].callback = callback;
139
        SREG = sreg;
140
    }
141
}
142
 
1138 linlun 143
#endif  /*PCINT_NUM_PCINTS > 0*/
144
 
1125 linlun 145
/*---------------------------------------------------------------------------*/
146