Rev 1851 | Rev 1871 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 1851 | Rev 1865 | ||
|---|---|---|---|
| Line 85... | Line 85... | ||
| 85 | uint8_t txindex; |
85 | uint8_t txindex; |
| 86 | irTxCallback_t callback; |
86 | irTxCallback_t callback; |
| 87 | volatile uint8_t *port; |
87 | volatile uint8_t *port; |
| 88 | uint8_t pinmask; |
88 | uint8_t pinmask; |
| 89 | } drvIrTxChannel[3]; |
89 | } drvIrTxChannel[3]; |
| - | 90 | ||
| - | 91 | uint16_t drvIrTxModFreqkHz = 38; /* Default to 38kHz */ |
|
| - | 92 | ||
| 90 | #endif |
93 | #endif |
| 91 | 94 | ||
| 92 | 95 | ||
| 93 | /*----------------------------------------------------------------------------- |
96 | /*----------------------------------------------------------------------------- |
| 94 | * Interrupt Handlers |
97 | * Interrupt Handlers |
| Line 125... | Line 128... | ||
| 125 | drvIrTxChannel[channel].timeout = IR_COMPARE_REG + drvIrTxChannel[channel].txbuf[drvIrTxChannel[channel].txindex++]; |
128 | drvIrTxChannel[channel].timeout = IR_COMPARE_REG + drvIrTxChannel[channel].txbuf[drvIrTxChannel[channel].txindex++]; |
| 126 | } |
129 | } |
| 127 | else |
130 | else |
| 128 | { |
131 | { |
| 129 | /* disable this channel */ |
132 | /* disable this channel */ |
| 130 | drvIrTxChannel[channel].timeoutEnable = FALSE; |
133 | drvIrTxChannel[channel].timeoutEnable = FALSE; |
| 131 | 134 | ||
| 132 | /* disable the overflow interrupt */ |
135 | /* disable the overflow interrupt */ |
| 133 | IR_MASK_COMPARE(); |
136 | IR_MASK_COMPARE(); |
| 134 | 137 | ||
| 135 | /* notify the application that a pulse train has been sent. */ |
138 | /* notify the application that a pulse train has been sent. */ |
| 136 | drvIrTxChannel[channel].callback(channel); |
139 | drvIrTxChannel[channel].callback(channel); |
| Line 210... | Line 213... | ||
| 210 | static uint16_t prev_time[3]; |
213 | static uint16_t prev_time[3]; |
| 211 | uint16_t pulsewidth; |
214 | uint16_t pulsewidth; |
| 212 | 215 | ||
| 213 | /* Read the timer counter register to get the current "time". */ |
216 | /* Read the timer counter register to get the current "time". */ |
| 214 | uint16_t time = IR_COUNT_REG; |
217 | uint16_t time = IR_COUNT_REG; |
| 215 | 218 | ||
| 216 | /* Subtract the current measurement from the previous to get the pulse width. */ |
219 | /* Subtract the current measurement from the previous to get the pulse width. */ |
| 217 | pulsewidth = time - prev_time[channel]; |
220 | pulsewidth = time - prev_time[channel]; |
| 218 | prev_time[channel] = time; |
221 | prev_time[channel] = time; |
| 219 | 222 | ||
| 220 | if (drvIrRxChannel[channel].storeEnable) |
223 | if (drvIrRxChannel[channel].storeEnable) |
| Line 291... | Line 294... | ||
| 291 | 294 | ||
| 292 | void IrTransceiver_DeInitRxChannel(uint8_t channel, uint8_t pcint_id, volatile uint8_t* port, volatile uint8_t* pin, volatile uint8_t* ddr,uint8_t nr, uint8_t pcint) |
295 | void IrTransceiver_DeInitRxChannel(uint8_t channel, uint8_t pcint_id, volatile uint8_t* port, volatile uint8_t* pin, volatile uint8_t* ddr,uint8_t nr, uint8_t pcint) |
| 293 | { |
296 | { |
| 294 | /* Deactivate interrupt */ |
297 | /* Deactivate interrupt */ |
| 295 | Pcint_SetCallback(pcint_id, pcint, 0); |
298 | Pcint_SetCallback(pcint_id, pcint, 0); |
| 296 | 299 | ||
| 297 | if (channel < 3) |
300 | if (channel < 3) |
| 298 | { |
301 | { |
| 299 | /* Deactivate channel */ |
302 | /* Deactivate channel */ |
| 300 | drvIrRxChannel[channel].enable = FALSE; |
303 | drvIrRxChannel[channel].enable = FALSE; |
| 301 | drvIrRxChannel[channel].rxlen = 0; |
304 | drvIrRxChannel[channel].rxlen = 0; |
| 302 | drvIrRxChannel[channel].storeEnable = FALSE; |
305 | drvIrRxChannel[channel].storeEnable = FALSE; |
| 303 | drvIrRxChannel[channel].callback = 0; |
306 | drvIrRxChannel[channel].callback = 0; |
| 304 | } |
307 | } |
| 305 | } |
308 | } |
| 306 | 309 | ||
| 307 | uint8_t IrTransceiver_GetStoreEnableRx(uint8_t channel) |
310 | uint8_t IrTransceiver_GetStoreEnableRx(uint8_t channel) |
| 308 | { |
311 | { |
| 309 | return drvIrRxChannel[channel].storeEnable; |
312 | return drvIrRxChannel[channel].storeEnable; |
| 310 | } |
313 | } |
| 311 | 314 | ||
| 312 | void IrTransceiver_DisableRx(uint8_t channel) |
315 | void IrTransceiver_DisableRx(uint8_t channel) |
| 313 | { |
316 | { |
| 314 | if (channel < 3) |
317 | if (channel < 3) |
| 315 | { |
318 | { |
| 316 | /* Soft disable channel */ |
319 | /* Soft disable channel */ |
| Line 326... | Line 329... | ||
| 326 | drvIrRxChannel[channel].enable = TRUE; |
329 | drvIrRxChannel[channel].enable = TRUE; |
| 327 | } |
330 | } |
| 328 | } |
331 | } |
| 329 | 332 | ||
| 330 | void IrTransceiver_ResetRx(uint8_t channel) |
333 | void IrTransceiver_ResetRx(uint8_t channel) |
| 331 | { |
334 | { |
| 332 | if (channel < 3) |
335 | if (channel < 3) |
| 333 | { |
336 | { |
| 334 | /* Reset channel */ |
337 | /* Reset channel */ |
| 335 | drvIrRxChannel[channel].rxlen = 0; |
338 | drvIrRxChannel[channel].rxlen = 0; |
| 336 | drvIrRxChannel[channel].storeEnable = FALSE; |
339 | drvIrRxChannel[channel].storeEnable = FALSE; |
| 337 | } |
340 | } |
| 338 | } |
341 | } |
| 339 | #endif |
342 | #endif |
| 340 | 343 | ||
| 341 | 344 | ||
| 342 | void IrTransceiver_Init(void) |
345 | void IrTransceiver_Init(void) |
| 343 | { |
346 | { |
| 344 | IR_TIMER_INIT(); |
347 | IR_TIMER_INIT(); |
| 345 | 348 | ||
| Line 355... | Line 358... | ||
| 355 | /* Set up transmitter */ |
358 | /* Set up transmitter */ |
| 356 | #if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) |
359 | #if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) |
| 357 | TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(1<<WGM01)|(0<<WGM00); |
360 | TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(1<<WGM01)|(0<<WGM00); |
| 358 | TCCR0B = (0<<WGM02)|(1<<CS00)|(0<<CS01)|(0<<CS02); |
361 | TCCR0B = (0<<WGM02)|(1<<CS00)|(0<<CS01)|(0<<CS02); |
| 359 | 362 | ||
| 360 | /* |
363 | /* Set up modulation frequency */ |
| 361 | IR_MODULATION_REG = (((F_CPU |
364 | IR_MODULATION_REG = (((F_CPU / 2000) / drvIrTxModFreqkHz) - 1); |
| 362 | 365 | ||
| 363 | /* start pwm generator */ |
366 | /* start pwm generator */ |
| 364 | TCCR0A |= (1<<COM0A0); |
367 | TCCR0A |= (1<<COM0A0); |
| 365 | #endif |
368 | #endif |
| 366 | 369 | ||
| Line 385... | Line 388... | ||
| 385 | drvIrTxChannel[channel].enable = TRUE; |
388 | drvIrTxChannel[channel].enable = TRUE; |
| 386 | drvIrTxChannel[channel].timeoutEnable = FALSE; |
389 | drvIrTxChannel[channel].timeoutEnable = FALSE; |
| 387 | } |
390 | } |
| 388 | } |
391 | } |
| 389 | 392 | ||
| 390 |
|
393 | int IrTransceiver_Transmit(uint8_t channel, uint16_t *buffer, uint8_t start, uint8_t length, uint16_t modfreqkHz) |
| 391 | { |
394 | { |
| - | 395 | if (modfreqkHz == 0) { |
|
| - | 396 | /* Invalid frequency. */ |
|
| 392 |
|
397 | return -1; |
| - | 398 | } |
|
| - | 399 | ||
| - | 400 | if (length == 0) { |
|
| 393 |
|
401 | /* No data. */ |
| - | 402 | return -2; |
|
| - | 403 | } |
|
| - | 404 | ||
| - | 405 | if (drvIrTxChannel[channel].timeoutEnable == TRUE) { |
|
| - | 406 | /* Channel busy. */ |
|
| - | 407 | return -3; |
|
| - | 408 | } |
|
| - | 409 | ||
| - | 410 | /* New modulation frequency. */ |
|
| - | 411 | if (modfreqkHz != drvIrTxModFreqkHz) { |
|
| - | 412 | /* Check that no transmissions are ongoing. */ |
|
| - | 413 | for (uint8_t i = 0; i < IR_SUPPORTED_NUM_CHANNELS; i++) { |
|
| - | 414 | /* Channel is waiting for an overflow. */ |
|
| - | 415 | if (drvIrTxChannel[i].timeoutEnable == TRUE) { |
|
| - | 416 | /* Transmission active. */ |
|
| - | 417 | return -4; |
|
| - | 418 | } |
|
| - | 419 | } |
|
| - | 420 | } |
|
| - | 421 | ||
| - | 422 | /* Update modulation frequency. */ |
|
| - | 423 | drvIrTxModFreqkHz = modfreqkHz; |
|
| 394 | 424 | ||
| 395 | if (length > 0) |
- | |
| 396 | { |
- | |
| 397 |
|
425 | /* Start new transmission. */ |
| 398 | { |
- | |
| 399 | drvIrTxChannel[channel].timeoutEnable = TRUE; |
426 | drvIrTxChannel[channel].timeoutEnable = TRUE; |
| 400 | drvIrTxChannel[channel].txbuf = buffer; |
427 | drvIrTxChannel[channel].txbuf = buffer; |
| 401 | drvIrTxChannel[channel].txlen = start+length; |
428 | drvIrTxChannel[channel].txlen = start + length; |
| - | 429 | ||
| 402 | /* first value will be loaded directly to timer below, therefore index is set to 1 here */ |
430 | /* first value will be loaded directly to timer below, therefore index is set to 1 here */ |
| 403 | drvIrTxChannel[channel].txindex = 1+start; |
431 | drvIrTxChannel[channel].txindex = 1 + start; |
| 404 | drvIrTxChannel[channel].timeout = IR_COUNT_REG + drvIrTxChannel[channel].txbuf[start]; |
432 | drvIrTxChannel[channel].timeout = IR_COUNT_REG + drvIrTxChannel[channel].txbuf[start]; |
| 405 | - | ||
| 406 | 433 | ||
| 407 | findchannel = 0; |
- | |
| 408 | diff = 0xffff; |
- | |
| 409 | uint16_t time = IR_COMPARE_REG; |
- | |
| 410 | /* go through all channels and find the one that have the next overflow */ |
434 | /* go through all channels and find the one that have the next overflow */ |
| - | 435 | uint8_t nextChannel = 0; |
|
| - | 436 | uint16_t timeRemaining = 0xffff; |
|
| - | 437 | uint16_t timeNow = IR_COMPARE_REG; |
|
| 411 | for (uint8_t i=0; i < IR_SUPPORTED_NUM_CHANNELS; i++) |
438 | for (uint8_t i = 0; i < IR_SUPPORTED_NUM_CHANNELS; i++) |
| 412 | { |
439 | { |
| 413 |
|
440 | /* channel is not waiting for an overflow */ |
| 414 |
|
441 | if (drvIrTxChannel[i].timeoutEnable == FALSE) continue; |
| 415 | { |
442 | |
| 416 |
|
443 | if (drvIrTxChannel[i].timeout - timeNow < timeRemaining) // || (timeout - time > 0xffff-IR_MAX_PULSE_WIDTH) |
| 417 | { |
444 | { |
| 418 |
|
445 | timeRemaining = drvIrTxChannel[i].timeout - timeNow; |
| 419 |
|
446 | nextChannel = i; |
| 420 | } |
- | |
| 421 | } |
447 | } |
| 422 | } |
448 | } |
| 423 | 449 | ||
| 424 | /* set compare value to the channel that have the next overflow */ |
450 | /* set compare value to the channel that have the next overflow */ |
| 425 |
|
451 | IR_COMPARE_REG = drvIrTxChannel[nextChannel].timeout; |
| - | 452 | ||
| - | 453 | /* set up modulation frequency */ |
|
| - | 454 | IR_MODULATION_REG = (((F_CPU / 2000) / drvIrTxModFreqkHz) - 1); |
|
| 426 | 455 | ||
| 427 | /* Start send on pin */ |
456 | /* Start send on pin */ |
| 428 | IR_OUTP_HIGH(); |
457 | IR_OUTP_HIGH(); |
| 429 | 458 | ||
| 430 | /* enable overflow interrupt */ |
459 | /* enable overflow interrupt */ |
| 431 | IR_UNMASK_COMPARE(); |
460 | IR_UNMASK_COMPARE(); |
| 432 | } |
- | |
| 433 | } |
- | |
| 434 | } |
461 | } |
| 435 | #endif |
462 | #endif |
| 436 | 463 | ||