Rev 1931 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 1931 | Rev 2198 | ||
|---|---|---|---|
| Line 69... | Line 69... | ||
| 69 | *---------------------------------------------------------------------------*/ |
69 | *---------------------------------------------------------------------------*/ |
| 70 | #if IR_RX_ENABLE==1 |
70 | #if IR_RX_ENABLE==1 |
| 71 | struct { |
71 | struct { |
| 72 | uint8_t enable; |
72 | uint8_t enable; |
| 73 | uint16_t timeout; |
73 | uint16_t timeout; |
| 74 | uint16_t * |
74 | uint16_t *buf; |
| 75 | uint8_t |
75 | uint8_t len; |
| - | 76 | uint8_t index; |
|
| 76 | uint8_t storeEnable; |
77 | uint8_t storeEnable; |
| 77 | irRxCallback_t callback; |
78 | irRxCallback_t callback; |
| 78 | } drvIrRxChannel[3]; |
79 | } drvIrRxChannel[3]; |
| 79 | #endif |
80 | #endif |
| 80 | 81 | ||
| 81 | #if IR_TX_ENABLE==1 |
82 | #if IR_TX_ENABLE==1 |
| 82 | struct { |
83 | struct { |
| 83 | uint8_t enable; |
84 | uint8_t enable; |
| 84 | uint16_t timeout; |
85 | uint16_t timeout; |
| 85 | uint8_t timeoutEnable; |
86 | uint8_t timeoutEnable; |
| 86 | uint16_t * |
87 | uint16_t *buf; |
| 87 | uint8_t |
88 | uint8_t len; |
| 88 | uint8_t |
89 | uint8_t index; |
| 89 | irTxCallback_t callback; |
90 | irTxCallback_t callback; |
| 90 | volatile uint8_t *port; |
91 | volatile uint8_t *port; |
| 91 | uint8_t pinmask; |
92 | uint8_t pinmask; |
| 92 | } drvIrTxChannel[3]; |
93 | } drvIrTxChannel[3]; |
| 93 | 94 | ||
| Line 118... | Line 119... | ||
| 118 | /* check if channel have overflowed or is about to overflow */ |
119 | /* check if channel have overflowed or is about to overflow */ |
| 119 | diff = (time+50)-drvIrTxChannel[channel].timeout; |
120 | diff = (time+50)-drvIrTxChannel[channel].timeout; |
| 120 | if (diff < IR_MAX_PULSE_WIDTH) |
121 | if (diff < IR_MAX_PULSE_WIDTH) |
| 121 | { |
122 | { |
| 122 | /* check what to output next */ |
123 | /* check what to output next */ |
| 123 | if ((drvIrTxChannel[channel]. |
124 | if ((drvIrTxChannel[channel].index&1) == 1) { /* if odd, ir-pause */ |
| 124 | IR_OUTP_LOW(); |
125 | IR_OUTP_LOW(); |
| 125 | } else { |
126 | } else { |
| 126 | IR_OUTP_HIGH(); |
127 | IR_OUTP_HIGH(); |
| 127 | } |
128 | } |
| 128 | 129 | ||
| 129 | /* is there more to send */ |
130 | /* is there more to send */ |
| 130 | if (drvIrTxChannel[channel]. |
131 | if (drvIrTxChannel[channel].index < drvIrTxChannel[channel].len) |
| 131 | { |
132 | { |
| 132 | /* load next timeout value */ |
133 | /* load next timeout value */ |
| 133 | drvIrTxChannel[channel].timeout = IR_COMPARE_REG + drvIrTxChannel[channel]. |
134 | drvIrTxChannel[channel].timeout = IR_COMPARE_REG + drvIrTxChannel[channel].buf[drvIrTxChannel[channel].index++]; |
| 134 | } |
135 | } |
| 135 | else |
136 | else |
| 136 | { |
137 | { |
| 137 | /* disable this channel */ |
138 | /* disable this channel */ |
| 138 | drvIrTxChannel[channel].timeoutEnable = FALSE; |
139 | drvIrTxChannel[channel].timeoutEnable = FALSE; |
| Line 178... | Line 179... | ||
| 178 | { |
179 | { |
| 179 | #if IR_RX_CONTINUOUS_MODE==0 |
180 | #if IR_RX_CONTINUOUS_MODE==0 |
| 180 | for (uint8_t i=0; i < IR_SUPPORTED_NUM_CHANNELS; i++) |
181 | for (uint8_t i=0; i < IR_SUPPORTED_NUM_CHANNELS; i++) |
| 181 | { |
182 | { |
| 182 | /* If more than 2 edges were recevied */ |
183 | /* If more than 2 edges were recevied */ |
| 183 | if (drvIrRxChannel[i].storeEnable == TRUE && drvIrRxChannel[i]. |
184 | if (drvIrRxChannel[i].storeEnable == TRUE && drvIrRxChannel[i].len > 2) |
| 184 | { |
185 | { |
| 185 | /* Notify the application that a pulse train has been received. */ |
186 | /* Notify the application that a pulse train has been received. */ |
| 186 | drvIrRxChannel[i].callback(i, drvIrRxChannel[i]. |
187 | drvIrRxChannel[i].callback(i, drvIrRxChannel[i].buf, drvIrRxChannel[i].len, drvIrRxChannel[i].index); |
| 187 | } |
188 | } |
| 188 | 189 | ||
| 189 | drvIrRxChannel[i].storeEnable = FALSE; |
190 | drvIrRxChannel[i].storeEnable = FALSE; |
| 190 | } |
191 | } |
| 191 | 192 | ||
| Line 215... | Line 216... | ||
| 215 | void IrTransceiver_Store_ch2(uint8_t id, uint8_t status) |
216 | void IrTransceiver_Store_ch2(uint8_t id, uint8_t status) |
| 216 | { |
217 | { |
| 217 | IrTransceiver_Store(2); |
218 | IrTransceiver_Store(2); |
| 218 | } |
219 | } |
| 219 | 220 | ||
| - | 221 | ||
| - | 222 | ///////////// DEBUG!!!! |
|
| - | 223 | //#include <drivers/mcu/gpio.h> |
|
| 220 | void IrTransceiver_Store(uint8_t channel) |
224 | void IrTransceiver_Store(uint8_t channel) |
| 221 | { |
225 | { |
| 222 | static uint16_t prev_time[3]; |
226 | static uint16_t prev_time[3]; |
| 223 | uint16_t pulsewidth; |
227 | uint16_t pulsewidth; |
| 224 | 228 | ||
| Line 228... | Line 232... | ||
| 228 | /* Subtract the current measurement from the previous to get the pulse width. */ |
232 | /* Subtract the current measurement from the previous to get the pulse width. */ |
| 229 | pulsewidth = time - prev_time[channel]; |
233 | pulsewidth = time - prev_time[channel]; |
| 230 | prev_time[channel] = time; |
234 | prev_time[channel] = time; |
| 231 | 235 | ||
| 232 | #if IR_MIN_STARTPULSE_WIDTH>0 |
236 | #if IR_MIN_STARTPULSE_WIDTH>0 |
| 233 | if ((pulsewidth <= IR_MIN_STARTPULSE_WIDTH) && (drvIrRxChannel[channel].storeEnable == TRUE) && (drvIrRxChannel[channel]. |
237 | if ((pulsewidth <= IR_MIN_STARTPULSE_WIDTH) && (drvIrRxChannel[channel].storeEnable == TRUE) && (drvIrRxChannel[channel].len == 0)) |
| 234 | { |
238 | { |
| 235 | IR_MASK_TIMEOUT(); |
239 | IR_MASK_TIMEOUT(); |
| 236 | return; |
240 | return; |
| 237 | } |
241 | } |
| 238 | else |
242 | else |
| Line 240... | Line 244... | ||
| 240 | IR_UNMASK_TIMEOUT(); |
244 | IR_UNMASK_TIMEOUT(); |
| 241 | } |
245 | } |
| 242 | #endif |
246 | #endif |
| 243 | //gpio_toggle_pin(EXP_K); |
247 | //gpio_toggle_pin(EXP_K); |
| 244 | 248 | ||
| 245 | #if |
249 | #if IR_RX_CONTINUOUS_MODE==1 |
| 246 | /* in continuous mode when short pulse arrives received len should be set to zero */ |
250 | /* in continuous mode when short pulse arrives received len should be set to zero */ |
| 247 | //TODO |
251 | //TODO? |
| 248 | if ((pulsewidth < |
252 | if ((pulsewidth < (IR_MIN_PULSE_WIDTH*CYCLES_PER_US/TIMER_PRESC)) && (drvIrRxChannel[channel].storeEnable == TRUE)) |
| 249 | { |
253 | { |
| - | 254 | ///////////// DEBUG!!!! |
|
| - | 255 | //gpio_toggle_pin(EXP_A); |
|
| 250 | drvIrRxChannel[channel]. |
256 | drvIrRxChannel[channel].len = 0; |
| 251 | //IR_MASK_TIMEOUT(); |
- | |
| 252 | return; |
257 | return; |
| 253 | } |
258 | } |
| 254 | else |
259 | else |
| 255 | { |
260 | { |
| 256 | //IR_UNMASK_TIMEOUT(); |
- | |
| 257 | } |
261 | } |
| 258 | #endif |
262 | #endif |
| - | 263 | //gpio_toggle_pin(EXP_A); |
|
| 259 | 264 | ||
| 260 | 265 | ||
| 261 | if (drvIrRxChannel[channel].storeEnable) |
266 | if (drvIrRxChannel[channel].storeEnable) |
| 262 | { |
267 | { |
| 263 | /* Store the measurement. */ |
268 | /* Store the measurement. */ |
| 264 | drvIrRxChannel[channel]. |
269 | drvIrRxChannel[channel].buf[drvIrRxChannel[channel].len++] = pulsewidth; |
| 265 | 270 | ||
| 266 | /* Disable future measurements if we've filled the buffer. */ |
271 | /* Disable future measurements if we've filled the buffer. */ |
| 267 | //TODO: Report overflow to application |
272 | //TODO: Report overflow to application |
| 268 | if (drvIrRxChannel[channel]. |
273 | if (drvIrRxChannel[channel].len == MAX_NR_TIMES) |
| 269 | { |
274 | { |
| 270 | drvIrRxChannel[channel]. |
275 | drvIrRxChannel[channel].len = MAX_NR_TIMES-1; |
| 271 | } |
276 | } |
| 272 | else |
277 | else |
| 273 | { |
278 | { |
| 274 | #if IR_RX_CONTINUOUS_MODE==0 |
279 | #if IR_RX_CONTINUOUS_MODE==0 |
| 275 | /* Set the timeout for detection of the end of the pulse train. */ |
280 | /* Set the timeout for detection of the end of the pulse train. */ |
| 276 | drvIrRxChannel[channel].timeout = time + IR_MAX_PULSE_WIDTH; |
281 | drvIrRxChannel[channel].timeout = time + (IR_MAX_PULSE_WIDTH*CYCLES_PER_US/TIMER_PRESC); |
| 277 | IR_TIMEOUT_REG = drvIrRxChannel[channel].timeout; |
282 | IR_TIMEOUT_REG = drvIrRxChannel[channel].timeout; |
| 278 | #else |
283 | #else |
| 279 | /* Notify the application that a pulse has been received. */ |
284 | /* Notify the application that a pulse has been received. */ |
| 280 | drvIrRxChannel[ |
285 | drvIrRxChannel[channel].callback(channel, drvIrRxChannel[channel].buf, drvIrRxChannel[channel].len, drvIrRxChannel[channel].index); |
| 281 | #endif |
286 | #endif |
| 282 | 287 | ||
| 283 | } |
288 | } |
| 284 | } |
289 | } |
| 285 | else if (drvIrRxChannel[channel].enable == TRUE) |
290 | else if (drvIrRxChannel[channel].enable == TRUE) |
| 286 | { |
291 | { |
| 287 | /* The first edge of the pulse train has been detected. Enable the storage of the following pulsewidths. */ |
292 | /* The first edge of the pulse train has been detected. Enable the storage of the following pulsewidths. */ |
| 288 | drvIrRxChannel[channel].storeEnable = TRUE; |
293 | drvIrRxChannel[channel].storeEnable = TRUE; |
| 289 | drvIrRxChannel[channel]. |
294 | drvIrRxChannel[channel].len = 0; |
| 290 | 295 | ||
| 291 | #if IR_RX_CONTINUOUS_MODE==0 |
296 | #if IR_RX_CONTINUOUS_MODE==0 |
| 292 | /* Enable timeout interrupt for detection of the end of the pulse train. */ |
297 | /* Enable timeout interrupt for detection of the end of the pulse train. */ |
| 293 | IR_TIMEOUT_REG = time + IR_MAX_PULSE_WIDTH; |
298 | IR_TIMEOUT_REG = time + (IR_MAX_PULSE_WIDTH*CYCLES_PER_US/TIMER_PRESC); |
| 294 | IR_UNMASK_TIMEOUT(); |
299 | IR_UNMASK_TIMEOUT(); |
| 295 | #endif |
300 | #endif |
| 296 | } |
301 | } |
| 297 | } |
302 | } |
| 298 | #endif |
303 | #endif |
| Line 324... | Line 329... | ||
| 324 | if (channel < 3) |
329 | if (channel < 3) |
| 325 | { |
330 | { |
| 326 | /* Set port direction to input */ |
331 | /* Set port direction to input */ |
| 327 | *ddr &= ~(1 << nr); |
332 | *ddr &= ~(1 << nr); |
| 328 | 333 | ||
| 329 | drvIrRxChannel[channel]. |
334 | drvIrRxChannel[channel].buf = buffer; |
| 330 | drvIrRxChannel[channel]. |
335 | drvIrRxChannel[channel].len = 0; |
| 331 | drvIrRxChannel[channel].storeEnable = FALSE; |
336 | drvIrRxChannel[channel].storeEnable = FALSE; |
| 332 | drvIrRxChannel[channel].callback = callback; |
337 | drvIrRxChannel[channel].callback = callback; |
| 333 | drvIrRxChannel[channel].enable = TRUE; |
338 | drvIrRxChannel[channel].enable = TRUE; |
| 334 | } |
339 | } |
| 335 | } |
340 | } |
| Line 345... | Line 350... | ||
| 345 | 350 | ||
| 346 | if (channel < 3) |
351 | if (channel < 3) |
| 347 | { |
352 | { |
| 348 | /* Deactivate channel */ |
353 | /* Deactivate channel */ |
| 349 | drvIrRxChannel[channel].enable = FALSE; |
354 | drvIrRxChannel[channel].enable = FALSE; |
| 350 | drvIrRxChannel[channel]. |
355 | drvIrRxChannel[channel].len = 0; |
| 351 | drvIrRxChannel[channel].storeEnable = FALSE; |
356 | drvIrRxChannel[channel].storeEnable = FALSE; |
| 352 | drvIrRxChannel[channel].callback = 0; |
357 | drvIrRxChannel[channel].callback = 0; |
| 353 | } |
358 | } |
| 354 | } |
359 | } |
| 355 | 360 | ||
| Line 379... | Line 384... | ||
| 379 | void IrTransceiver_ResetRx(uint8_t channel) |
384 | void IrTransceiver_ResetRx(uint8_t channel) |
| 380 | { |
385 | { |
| 381 | if (channel < 3) |
386 | if (channel < 3) |
| 382 | { |
387 | { |
| 383 | /* Reset channel */ |
388 | /* Reset channel */ |
| 384 | drvIrRxChannel[channel]. |
389 | drvIrRxChannel[channel].len = 0; |
| 385 | drvIrRxChannel[channel].storeEnable = FALSE; |
390 | drvIrRxChannel[channel].storeEnable = FALSE; |
| 386 | } |
391 | } |
| 387 | } |
392 | } |
| 388 | #endif |
393 | #endif |
| 389 | 394 | ||
| Line 394... | Line 399... | ||
| 394 | 399 | ||
| 395 | #if IR_RX_ENABLE==1 |
400 | #if IR_RX_ENABLE==1 |
| 396 | for (uint8_t i = 0; i < 3; i++) |
401 | for (uint8_t i = 0; i < 3; i++) |
| 397 | { |
402 | { |
| 398 | drvIrRxChannel[i].storeEnable = FALSE; |
403 | drvIrRxChannel[i].storeEnable = FALSE; |
| 399 | drvIrRxChannel[i]. |
404 | drvIrRxChannel[i].len = 0; |
| 400 | } |
405 | } |
| 401 | #endif |
406 | #endif |
| 402 | 407 | ||
| 403 | #if IR_TX_ENABLE==1 |
408 | #if IR_TX_ENABLE==1 |
| 404 | /* Set up transmitter */ |
409 | /* Set up transmitter */ |
| Line 468... | Line 473... | ||
| 468 | /* Update modulation frequency. */ |
473 | /* Update modulation frequency. */ |
| 469 | drvIrTxModFreqkHz = modfreqkHz; |
474 | drvIrTxModFreqkHz = modfreqkHz; |
| 470 | 475 | ||
| 471 | /* Start new transmission. */ |
476 | /* Start new transmission. */ |
| 472 | drvIrTxChannel[channel].timeoutEnable = TRUE; |
477 | drvIrTxChannel[channel].timeoutEnable = TRUE; |
| 473 | drvIrTxChannel[channel]. |
478 | drvIrTxChannel[channel].buf = buffer; |
| 474 | drvIrTxChannel[channel]. |
479 | drvIrTxChannel[channel].len = start + length; |
| 475 | 480 | ||
| 476 | /* first value will be loaded directly to timer below, therefore index is set to 1 here */ |
481 | /* first value will be loaded directly to timer below, therefore index is set to 1 here */ |
| 477 | drvIrTxChannel[channel]. |
482 | drvIrTxChannel[channel].index = 1 + start; |
| 478 | drvIrTxChannel[channel].timeout = IR_COUNT_REG + drvIrTxChannel[channel]. |
483 | drvIrTxChannel[channel].timeout = IR_COUNT_REG + drvIrTxChannel[channel].buf[start]; |
| 479 | 484 | ||
| 480 | /* go through all channels and find the one that have the next overflow */ |
485 | /* go through all channels and find the one that have the next overflow */ |
| 481 | uint8_t nextChannel = 0; |
486 | uint8_t nextChannel = 0; |
| 482 | uint16_t timeRemaining = 0xffff; |
487 | uint16_t timeRemaining = 0xffff; |
| 483 | uint16_t timeNow = IR_COMPARE_REG; |
488 | uint16_t timeNow = IR_COMPARE_REG; |