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 | /* |
101 | /* find which channel */ |
| - | 102 | uint16_t time = IR_COMPARE_REG; |
|
| - | 103 | uint16_t diff; |
|
| 128 | uint8_t channel |
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 |
|
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 | /* |
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 | /* |
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 */ |