Subversion Repositories HomeAutomation

Rev

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
    /* set up modulation frequency to 38kHz */
363
    /* Set up modulation frequency */
361
    IR_MODULATION_REG = (((F_CPU/2000)/38) -1);
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
void IrTransceiver_Transmit(uint8_t channel, uint16_t *buffer, uint8_t start, uint8_t length)
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
    uint16_t diff;
397
        return -1;
-
 
398
    }
-
 
399
 
-
 
400
    if (length == 0) {
393
    uint8_t findchannel;
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
        if (drvIrTxChannel[channel].timeoutEnable == FALSE)
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
                /* if channel is waiting for an overflow */
440
        /* channel is not waiting for an overflow */
414
                if (drvIrTxChannel[i].timeoutEnable==TRUE)
441
        if (drvIrTxChannel[i].timeoutEnable == FALSE) continue;
415
                {
442
 
416
                    if (drvIrTxChannel[i].timeout - time < diff)    // || (timeout - time > 0xffff-IR_MAX_PULSE_WIDTH)
443
        if (drvIrTxChannel[i].timeout - timeNow < timeRemaining)    // || (timeout - time > 0xffff-IR_MAX_PULSE_WIDTH)
417
                    {
444
        {
418
                        diff = drvIrTxChannel[i].timeout - time;
445
            timeRemaining = drvIrTxChannel[i].timeout - timeNow;
419
                        findchannel = i;
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
            IR_COMPARE_REG = drvIrTxChannel[findchannel].timeout;
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