Subversion Repositories HomeAutomation

Rev

Rev 1488 | Rev 1730 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1488 Rev 1494
Line 19... Line 19...
19
#include <avr/interrupt.h>
19
#include <avr/interrupt.h>
20
 
20
 
21
/*-----------------------------------------------------------------------------
21
/*-----------------------------------------------------------------------------
22
 * Prerequisites
22
 * Prerequisites
23
 *---------------------------------------------------------------------------*/
23
 *---------------------------------------------------------------------------*/
24
//TODO: Use this define, might fix the bug
-
 
25
#ifndef IR_RX_ACTIVE_LOW
-
 
26
#define IR_RX_ACTIVE_LOW    1
-
 
27
#endif
-
 
28
 
-
 
29
#ifndef IR_TX_ACTIVE_LOW
-
 
30
#define IR_TX_ACTIVE_LOW    0
-
 
31
#endif
-
 
32
 
-
 
33
#ifndef IR_TX_ENABLE
-
 
34
#define IR_TX_ENABLE    0
-
 
35
#endif
-
 
36
 
-
 
37
#ifndef IR_RX_ENABLE
-
 
38
#define IR_RX_ENABLE    0
-
 
39
#endif
-
 
40
 
-
 
41
 
-
 
42
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
24
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
43
#define TIMSK1  TIMSK
25
#define TIMSK1  TIMSK
44
#define TIFR1   TIFR
26
#define TIFR1   TIFR
45
#define ICIE1   TICIE1
27
#define ICIE1   TICIE1
46
#endif
28
#endif
Line 63... Line 45...
63
#define IR_MASK_TIMEOUT()       TIMSK1 &= ~(1<<OCIE1A);
45
#define IR_MASK_TIMEOUT()       TIMSK1 &= ~(1<<OCIE1A);
64
#define IR_UNMASK_TIMEOUT()     TIFR1 = (1<<OCF1A); TIMSK1 |= (1<<OCIE1A);
46
#define IR_UNMASK_TIMEOUT()     TIFR1 = (1<<OCF1A); TIMSK1 |= (1<<OCIE1A);
65
#define IR_MASK_CAPTURE()       TIMSK1 &= ~(1<<ICIE1);
47
#define IR_MASK_CAPTURE()       TIMSK1 &= ~(1<<ICIE1);
66
#define IR_UNMASK_CAPTURE()     TIFR1 = (1<<ICF1); TIMSK1 |= (1<<ICIE1);
48
#define IR_UNMASK_CAPTURE()     TIFR1 = (1<<ICF1); TIMSK1 |= (1<<ICIE1);
67
#define IR_CAPTURE_FALLING()    TCCR1B &= ~(1<<ICES1); \
49
#define IR_CAPTURE_FALLING()    TCCR1B &= ~(1<<ICES1); \
68
                                TIFR1 = (1<<ICF1);
50
                                TIFR1 = (1<<ICF1);
69
#define IR_CAPTURE_RISING()     TCCR1B |= (1<<ICES1); \
51
#define IR_CAPTURE_RISING()     TCCR1B |= (1<<ICES1); \
70
                                TIFR1 = (1<<ICF1);
52
                                TIFR1 = (1<<ICF1);
71
 
53
 
72
//#define IR_OUTP_HIGH()            TCCR0A |= (1<<COM0A0);
54
//#define IR_OUTP_HIGH()            TCCR0A |= (1<<COM0A0);
73
//#define IR_OUTP_LOW()         TCCR0A &= ~(1<<COM0A0);
55
//#define IR_OUTP_LOW()         TCCR0A &= ~(1<<COM0A0);
Line 75... Line 57...
75
#define IR_OUTP_HIGH()  *drvIrTxChannel[channel].port &= ~drvIrTxChannel[channel].pinmask
57
#define IR_OUTP_HIGH()  *drvIrTxChannel[channel].port &= ~drvIrTxChannel[channel].pinmask
76
#define IR_OUTP_LOW()   *drvIrTxChannel[channel].port |= drvIrTxChannel[channel].pinmask
58
#define IR_OUTP_LOW()   *drvIrTxChannel[channel].port |= drvIrTxChannel[channel].pinmask
77
#else
59
#else
78
#define IR_OUTP_HIGH()  *drvIrTxChannel[channel].port |= drvIrTxChannel[channel].pinmask
60
#define IR_OUTP_HIGH()  *drvIrTxChannel[channel].port |= drvIrTxChannel[channel].pinmask
79
#define IR_OUTP_LOW()   *drvIrTxChannel[channel].port &= ~drvIrTxChannel[channel].pinmask
61
#define IR_OUTP_LOW()   *drvIrTxChannel[channel].port &= ~drvIrTxChannel[channel].pinmask
80
#endif
62
#endif
81
 
63
 
82
 
64
 
83
/*-----------------------------------------------------------------------------
65
/*-----------------------------------------------------------------------------
84
 * Globals
66
 * Globals
85
 *---------------------------------------------------------------------------*/
67
 *---------------------------------------------------------------------------*/
86
#if IR_RX_ENABLE==1
68
#if IR_RX_ENABLE==1
87
struct {
69
struct {
Line 111... Line 93...
111
 
93
 
112
 
94
 
113
/*-----------------------------------------------------------------------------
95
/*-----------------------------------------------------------------------------
114
 * Interrupt Handlers
96
 * Interrupt Handlers
115
 *---------------------------------------------------------------------------*/
97
 *---------------------------------------------------------------------------*/
116
 
-
 
117
 
-
 
118
/*
-
 
119
timer 1 has two comprare registers and compare ISRs, one is used below for "timeout" on receive and the other is used here for transmitter
-
 
120
//TODO: how to handle more than one transmitter on one compare interrupt, spara en array med tider och nån enableflagga för varje kanal
-
 
121
*/
-
 
122
 
-
 
123
#if IR_TX_ENABLE==1
98
#if IR_TX_ENABLE==1
124
ISR(IR_COMPARE_VECTOR)
99
ISR(IR_COMPARE_VECTOR)
125
{
100
{
126
 
-
 
127
    /* TODO find which channel */
101
    /* find which channel */
-
 
102
    uint16_t time = IR_COMPARE_REG;
-
 
103
    uint16_t diff;
128
    uint8_t channel = 0;
104
    uint8_t channel;
129
   
105
 
-
 
106
    /* go through all channels and check which of thems have overflowed */
-
 
107
    for (channel=0; channel < IR_SUPPORTED_NUM_CHANNELS; channel++)
130
   
108
    {
-
 
109
        /* if channel is waiting for an overflow */
-
 
110
        if (drvIrTxChannel[channel].timeoutEnable==TRUE)
-
 
111
        {
-
 
112
            /* check if channel have overflowed or is about to overflow */
-
 
113
            diff = (time+50)-drvIrTxChannel[channel].timeout;
-
 
114
            if (diff < IR_MAX_PULSE_WIDTH)
-
 
115
            {
-
 
116
                /* check what to output next */
131
    if ((drvIrTxChannel[channel].txindex&1) == 1) {     /* if odd, ir-pause */
117
                if ((drvIrTxChannel[channel].txindex&1) == 1) {     /* if odd, ir-pause */
132
        IR_OUTP_LOW();
118
                    IR_OUTP_LOW();
133
    } else {
119
                } else {
134
        IR_OUTP_HIGH();
120
                    IR_OUTP_HIGH();
135
    }
121
                }
136
   
122
               
-
 
123
                /* is there more to send */
137
    if (drvIrTxChannel[channel].txindex < drvIrTxChannel[channel].txlen)
124
                if (drvIrTxChannel[channel].txindex < drvIrTxChannel[channel].txlen)
138
    {
125
                {
-
 
126
                    /* load next timeout value */
139
        drvIrTxChannel[channel].timeout = IR_COMPARE_REG + drvIrTxChannel[channel].txbuf[drvIrTxChannel[channel].txindex++];
127
                    drvIrTxChannel[channel].timeout = IR_COMPARE_REG + drvIrTxChannel[channel].txbuf[drvIrTxChannel[channel].txindex++];
140
    }
128
                }
141
    else
129
                else
142
    {
130
                {
143
        //TODO only mask if noone is sending (checked below)
131
                    /* disable this channel */
144
        IR_MASK_COMPARE();
-
 
145
       
-
 
146
        drvIrTxChannel[channel].timeoutEnable = FALSE;
132
                    drvIrTxChannel[channel].timeoutEnable = FALSE;
147
       
133
 
-
 
134
                    /* disable the overflow interrupt */
-
 
135
                    IR_MASK_COMPARE();
-
 
136
       
148
        /* Notify the application that a pulse train has been sent. */
137
                    /* notify the application that a pulse train has been sent. */
149
        drvIrTxChannel[channel].callback(channel);
138
                    drvIrTxChannel[channel].callback(channel);
-
 
139
                }
-
 
140
            }
-
 
141
        }
-
 
142
    }
-
 
143
   
-
 
144
    channel = 0;
-
 
145
    diff = 0xffff;
-
 
146
    /* go through all channels and find the one that have the next overflow */
-
 
147
    for (uint8_t i=0; i < IR_SUPPORTED_NUM_CHANNELS; i++)
-
 
148
    {
-
 
149
        /* if channel is waiting for an overflow */
-
 
150
        if (drvIrTxChannel[i].timeoutEnable==TRUE)
-
 
151
        {
-
 
152
            if (drvIrTxChannel[i].timeout - time < diff)
-
 
153
            {
-
 
154
                diff = drvIrTxChannel[i].timeout - time;
-
 
155
                channel = i;
-
 
156
            }
-
 
157
            /* enable overflow interrupt */
-
 
158
            IR_UNMASK_COMPARE();
-
 
159
        }      
150
    }
160
    }  
151
 
161
 
152
    /* TODO: find channel with lowest time left */
162
    /* set compare value to the channel that have the next overflow */
153
    IR_COMPARE_REG = drvIrTxChannel[channel].timeout;
163
    IR_COMPARE_REG = drvIrTxChannel[channel].timeout;
154
}
164
}
155
#endif
165
#endif
156
 
166
 
157
#if IR_RX_ENABLE==1
167
#if IR_RX_ENABLE==1
158
//TODO: hur hantera detta i multi receiver
168
//TODO: hur hantera detta i multi receiver
159
//TODO: ha en array med tider och nån enableflagga för varje kanal
169
//TODO: ha en array med tider och nån enableflagga för varje kanal
160
//TODO: mot slutet av ISRen laddas nästa tid in...
170
//TODO: mot slutet av ISRen laddas nästa tid in... likadant som för TX, se ovan ISR
161
 
171
 
162
/* When this timeout occurs a pulsetrain is complete */
172
/* When this timeout occurs a pulsetrain is complete */
163
ISR(IR_TIMEOUT_VECTOR)
173
ISR(IR_TIMEOUT_VECTOR)
164
{
174
{
165
    /* Find which channel timed out */
175
    /* Find which channel timed out */