Subversion Repositories HomeAutomation

Rev

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

Rev 1474 Rev 1479
Line 10... Line 10...
10
/*-----------------------------------------------------------------------------
10
/*-----------------------------------------------------------------------------
11
 * Includes
11
 * Includes
12
 *---------------------------------------------------------------------------*/
12
 *---------------------------------------------------------------------------*/
13
#include <config.h>
13
#include <config.h>
14
#include <drivers/mcu/pcint.h>
14
#include <drivers/mcu/pcint.h>
-
 
15
#include <drivers/mcu/gpio.h>
15
#include <drivers/ir/transceiver/irtransceiverMulti.h>
16
#include <drivers/ir/transceiver/irtransceiverMulti.h>
16
#include <drivers/ir/protocols.h>
17
#include <drivers/ir/protocols.h>
17
#include <avr/io.h>
18
#include <avr/io.h>
18
#include <avr/interrupt.h>
19
#include <avr/interrupt.h>
19
 
20
 
20
/*-----------------------------------------------------------------------------
21
/*-----------------------------------------------------------------------------
21
 * Globals
22
 * Globals
22
 *---------------------------------------------------------------------------*/
23
 *---------------------------------------------------------------------------*/
23
#if IR_RX_ENABLE==1
24
#if IR_RX_ENABLE==1
24
struct {
25
struct {
-
 
26
    uint8_t     enable;
25
    uint16_t    timeout;
27
    uint16_t    timeout;
26
    uint8_t     timeoutEnable;
28
    uint8_t     timeoutEnable;
27
    uint16_t    *rxbuf;
29
    uint16_t    *rxbuf;
28
    uint8_t     rxlen;
30
    uint8_t     rxlen;
29
    uint8_t     storeEnable;
31
    uint8_t     storeEnable;
30
    irCallback_t callback;
32
    irCallback_t callback;
31
} irRxChannel[3];
33
} drvIrRxChannel[3];
32
 
34
 
33
 
35
 
34
#endif
36
#endif
35
#if IR_TX_ENABLE==1
37
#if IR_TX_ENABLE==1
36
uint16_t *txbuf;
38
uint16_t *txbuf;
37
uint8_t txlen;
39
uint8_t txlen;
38
static uint8_t bufIndex;                            //selects the pulse width in buffer to send
40
static uint8_t bufIndex;                            //selects the pulse width in buffer to send
-
 
41
volatile uint8_t data_transmitted;
39
#endif
42
#endif
40
 
43
 
41
volatile uint8_t data_transmitted;
-
 
42
 
44
 
43
 
45
 
44
/*-----------------------------------------------------------------------------
46
/*-----------------------------------------------------------------------------
45
 * Prerequisites
47
 * Prerequisites
46
 *---------------------------------------------------------------------------*/
48
 *---------------------------------------------------------------------------*/
47
#ifndef IR_RX_ACTIVE_LOW
49
#ifndef IR_RX_ACTIVE_LOW
48
#define IR_RX_ACTIVE_LOW    1
50
#define IR_RX_ACTIVE_LOW    1
49
#endif
51
#endif
50
 
52
 
51
#ifndef IR_TX_ACTIVE_LOW
53
#ifndef IR_TX_ACTIVE_LOW
52
#define IR_TX_ACTIVE_LOW    0
54
#define IR_TX_ACTIVE_LOW    0
53
#endif
55
#endif
54
 
56
 
55
#ifndef IR_TX_ENABLE
57
#ifndef IR_TX_ENABLE
56
#define IR_TX_ENABLE    0
58
#define IR_TX_ENABLE    0
57
#endif
59
#endif
58
 
60
 
59
#ifndef IR_RX_ENABLE
61
#ifndef IR_RX_ENABLE
60
#define IR_RX_ENABLE    0
62
#define IR_RX_ENABLE    0
61
#endif
63
#endif
62
 
64
 
63
 
65
 
64
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
66
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
65
#define TIMSK1  TIMSK
67
#define TIMSK1  TIMSK
66
#define TIFR1   TIFR
68
#define TIFR1   TIFR
67
#define ICIE1   TICIE1
69
#define ICIE1   TICIE1
68
#endif
70
#endif
69
 
71
 
70
#define IR_COMPARE_VECTOR       TIMER1_COMPB_vect
72
#define IR_COMPARE_VECTOR       TIMER1_COMPB_vect
71
#define IR_TIMEOUT_VECTOR       TIMER1_COMPA_vect
73
#define IR_TIMEOUT_VECTOR       TIMER1_COMPA_vect
72
#define IR_CAPTURE_VECTOR       TIMER1_CAPT_vect
74
#define IR_CAPTURE_VECTOR       TIMER1_CAPT_vect
73
#define IR_TIMEOUT_REG          OCR1A
75
#define IR_TIMEOUT_REG          OCR1A
74
#define IR_COMPARE_REG          OCR1B
76
#define IR_COMPARE_REG          OCR1B
Line 139... Line 141...
139
//TODO: mot slutet av ISRen laddas nästa tid in...
141
//TODO: mot slutet av ISRen laddas nästa tid in...
140
 
142
 
141
/* When this timeout occurs a pulsetrain is complete */
143
/* When this timeout occurs a pulsetrain is complete */
142
ISR(IR_TIMEOUT_VECTOR)
144
ISR(IR_TIMEOUT_VECTOR)
143
{
145
{
144
 
-
 
145
    /* Find which channel timed out */
146
    /* Find which channel timed out */
146
    uint16_t timeDiff = 0xffff;
147
    uint16_t timeDiff = 0xffff;
147
    uint8_t channel = 0;
148
    uint8_t channel = 0;
148
    for (uint8_t i=0; i < 3; i++)
149
/*  for (uint8_t i=0; i < 3; i++)
149
    {
150
    {
150
        if ((irRxChannel[channel].timeoutEnable) && (IR_TIMEOUT_REG-irRxChannel[i].timeout < timeDiff))
151
        if ((drvIrRxChannel[channel].timeoutEnable==TRUE) && (IR_TIMEOUT_REG-drvIrRxChannel[i].timeout < timeDiff))
151
        {
152
        {
152
            timeDiff = IR_TIMEOUT_REG-irRxChannel[i].timeout;
153
            timeDiff = IR_TIMEOUT_REG-drvIrRxChannel[i].timeout;
153
            channel = i;
154
            channel = i;
154
        }
155
        }
155
    }
156
    }
156
 
157
*/
157
    /* If more than 3 flanks was recevied */
158
    /* If more than 3 flanks was recevied */
158
    if (irRxChannel[channel].rxlen > 3)
159
    if (drvIrRxChannel[channel].rxlen > 3)
159
    {
160
    {
160
        /* Notify the application that a pulse train has been received. */
161
        /* Notify the application that a pulse train has been received. */
161
        irRxChannel[channel].callback(channel, irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen);
162
        drvIrRxChannel[channel].callback(channel, drvIrRxChannel[channel].rxbuf, drvIrRxChannel[channel].rxlen);
162
    }
163
    }
163
 
164
 
164
    irRxChannel[channel].storeEnable = FALSE;
165
    drvIrRxChannel[channel].storeEnable = FALSE;
165
    irRxChannel[channel].timeoutEnable = FALSE;
166
    drvIrRxChannel[channel].timeoutEnable = FALSE;
166
 
167
 
167
    IR_UNMASK_TIMEOUT();
168
    IR_MASK_TIMEOUT();
168
   
169
   
169
//TODO: reset the timeout for next enabled channel
170
//TODO: reset the timeout for next enabled channel
170
/*
171
/*
171
    uint16_t nextTimeout = irRxChannel[channel].timeout;
172
    uint16_t nextTimeout = drvIrRxChannel[channel].timeout;
172
    for (uint8_t i=0; i < 3; i++)
173
    for (uint8_t i=0; i < 3; i++)
173
    {
174
    {
174
//TODO: hitta den med timeout härnäst (svårt med tanke på att den tiden kan ha passerat eftersom vi är under interrupt)
175
//TODO: hitta den med timeout härnäst (svårt med tanke på att den tiden kan ha passerat eftersom vi är under interrupt)
175
//kanske inte är så noga, i värsta fall tar det 65ms extra
176
//kanske inte är så noga, i värsta fall tar det 65ms extra
176
        if ((irRxChannel[channel].timeoutEnable) && (irRxChannel[i].timeout < nextTimeout))
177
        if ((drvIrRxChannel[channel].timeoutEnable) && (drvIrRxChannel[i].timeout < nextTimeout))
177
        {
178
        {
178
            nextTimeout = irRxChannel[i].timeout;
179
            nextTimeout = drvIrRxChannel[i].timeout;
179
        }
180
        }
180
    }
181
    }
181
    IR_MASK_TIMEOUT();
182
    IR_UNMASK_TIMEOUT();
182
    IR_TIMEOUT_REG = nextTimeout;
183
    IR_TIMEOUT_REG = nextTimeout;
183
*/
184
*/
184
}
185
}
185
#endif
186
#endif
186
 
187
 
Line 205... Line 206...
205
    IrTransceiver_Store(2);
206
    IrTransceiver_Store(2);
206
}
207
}
207
 
208
 
208
void IrTransceiver_Store(uint8_t channel)
209
void IrTransceiver_Store(uint8_t channel)
209
{
210
{
210
    static uint16_t prev_time;
211
    static uint16_t prev_time[3];
211
    uint16_t pulsewidth;
212
    uint16_t pulsewidth;
212
 
213
 
213
    /* Read the measured transition time from the capture register. */
-
 
214
    //uint16_t time = IR_CAPTURE_REG;
-
 
215
    /* Read the timer counter register to get the current "time". */
214
    /* Read the timer counter register to get the current "time". */
216
    uint16_t time = IR_COUNT_REG;
215
    uint16_t time = IR_COUNT_REG;
217
       
216
   
218
    /* Subtract the current measurement from the previous to get the pulse
217
    /* Subtract the current measurement from the previous to get the pulse width. */
219
     * width. */
-
 
220
    pulsewidth = time - prev_time;
218
    pulsewidth = time - prev_time[channel];
221
    prev_time = time;
219
    prev_time[channel] = time;
222
   
220
 
223
    /* Set the timeout. */
-
 
224
    irRxChannel[channel].timeout = time + IR_MAX_PULSE_WIDTH;
-
 
225
    irRxChannel[channel].timeoutEnable = TRUE;
-
 
226
    uint16_t nextTimeout = irRxChannel[channel].timeout;
-
 
227
    for (uint8_t i=0; i < 3; i++)
-
 
228
    {
-
 
229
//TODO: hitta den med timeout härnäst (svårt med tanke på att den tiden kan ha passerat eftersom vi är under interrupt)
-
 
230
//kanske inte är så noga, i värsta fall tar det 65ms extra
-
 
231
        if ((irRxChannel[channel].timeoutEnable) && (irRxChannel[i].timeout < nextTimeout))
-
 
232
        {
-
 
233
            nextTimeout = irRxChannel[i].timeout;
-
 
234
        }
-
 
235
    }
-
 
236
    IR_TIMEOUT_REG = nextTimeout;
-
 
237
   
-
 
238
    if (irRxChannel[channel].storeEnable)
221
    if (drvIrRxChannel[channel].storeEnable)
239
    {
222
    {
240
        /* Store the measurement. */
223
        /* Store the measurement. */
241
        irRxChannel[channel].rxbuf[irRxChannel[channel].rxlen++] = pulsewidth;
224
        drvIrRxChannel[channel].rxbuf[drvIrRxChannel[channel].rxlen++] = pulsewidth;
242
 
225
 
243
        /* Disable future measurements if we've filled the buffer. */
226
        /* Disable future measurements if we've filled the buffer. */
244
        //TODO: What to do in multi recevier?
227
        //TODO: What to do in multi recevier?
245
        //TODO: Report overflow to application
228
        //TODO: Report overflow to application
246
        if (irRxChannel[channel].rxlen == MAX_NR_TIMES)
229
        if (drvIrRxChannel[channel].rxlen == MAX_NR_TIMES)
247
        {
230
        {
248
            irRxChannel[channel].rxlen = MAX_NR_TIMES-1;
231
            drvIrRxChannel[channel].rxlen = MAX_NR_TIMES-1;
249
            //IR_MASK_CAPTURE();
-
 
250
        }
232
        }
251
    }
233
    }
252
    else
234
    else if (drvIrRxChannel[channel].enable == TRUE)
253
    {
235
    {
254
        /* The first edge of the pulse train has been detected. Enable the
236
        /* The first edge of the pulse train has been detected. Enable the storage of the following pulsewidths. */
255
         * storage of the following pulsewidths. */
237
        drvIrRxChannel[channel].storeEnable = TRUE;
256
        irRxChannel[channel].storeEnable = TRUE;
238
        drvIrRxChannel[channel].rxlen = 0;
257
        irRxChannel[channel].rxlen = 0;
239
        drvIrRxChannel[channel].timeoutEnable = TRUE;
-
 
240
 
-
 
241
        /* Set the timeout for detection of the end of the pulse train. */
-
 
242
        drvIrRxChannel[channel].timeout = time + IR_MAX_PULSE_WIDTH;
-
 
243
        uint16_t nextTimeout = drvIrRxChannel[channel].timeout;
-
 
244
        for (uint8_t i=0; i < 3; i++)
-
 
245
        {
-
 
246
    //TODO: hitta den med timeout härnäst (svårt med tanke på att den tiden kan ha passerat eftersom vi är under interrupt)
-
 
247
    //kanske inte är så noga, i värsta fall tar det 65ms extra
-
 
248
            if ((drvIrRxChannel[channel].timeoutEnable) && (drvIrRxChannel[i].timeout < nextTimeout))
-
 
249
            {
-
 
250
                nextTimeout = drvIrRxChannel[i].timeout;
-
 
251
            }
-
 
252
        }
-
 
253
        IR_TIMEOUT_REG = nextTimeout;
-
 
254
 
258
        /* Enable timeout interrupt for detection of the end of the pulse train. */
255
        /* Enable timeout interrupt for detection of the end of the pulse train. */
259
        IR_UNMASK_TIMEOUT();
256
        IR_UNMASK_TIMEOUT();
260
 
257
 
261
        //TODO: if buffer resource coordinator is implemented this is where a buffer should be assinged to this channel
258
        //TODO: if buffer resource coordinator is implemented this is where a buffer should be assinged to this channel
262
    }
259
    }
263
}
260
}
264
#endif
261
#endif
265
 
262
 
266
 
263
 
267
/*-----------------------------------------------------------------------------
264
/*-----------------------------------------------------------------------------
268
 * Public Functions
265
 * Public Functions
269
 *---------------------------------------------------------------------------*/
266
 *---------------------------------------------------------------------------*/
270
 
267
 
271
/* call this function like this:
268
/* call this function like this:
272
    IrTransceiver_Init_TX_Channel(0, buffer, callback, pcint-id, GPIO_D6);
269
    IrTransceiver_Init_TX_Channel(channelnumber, buffer, callback, pcint-id, GPIO_D6);
273
    buffer is a memory location
270
    buffer is a memory location
274
    callback is a function to call when a receive/transmitt is complete
271
    callback is a function to call when a receive/transmitt is complete
275
    also call with IO port to use
272
    also call with IO port to use  
276
   
-
 
277
    function to deactivate channel may later be needed
-
 
278
*/
273
*/
279
 
274
 
280
#if IR_RX_ENABLE==1
275
#if IR_RX_ENABLE==1
281
void IrTransceiver_Init_TX_Channel(uint8_t channel, uint16_t *buffer, irCallback_t callback, uint8_t pcint_id, volatile uint8_t* port, volatile uint8_t* pin, volatile uint8_t* ddr,uint8_t nr, uint8_t pcint)
276
void IrTransceiver_Init_TX_Channel(uint8_t channel, uint16_t *buffer, irCallback_t callback, uint8_t pcint_id, volatile uint8_t* port, volatile uint8_t* pin, volatile uint8_t* ddr,uint8_t nr, uint8_t pcint)
282
{
277
{
283
    if (channel == 0)
278
    if (channel == 0)
284
    {
279
    {
285
        Pcint_SetCallback(pcint_id, pcint, &IrTransceiver_Store_ch0);
280
        Pcint_SetCallback(pcint_id, pcint, &IrTransceiver_Store_ch0);
286
    }
281
    }
287
    else if (channel == 1)
282
    else if (channel == 1)
288
    {
283
    {
289
        Pcint_SetCallback(pcint_id, pcint, &IrTransceiver_Store_ch1);
284
        Pcint_SetCallback(pcint_id, pcint, &IrTransceiver_Store_ch1);
290
    }
285
    }
291
    else if (channel == 2)
286
    else if (channel == 2)
292
    {
287
    {
293
        Pcint_SetCallback(pcint_id, pcint, &IrTransceiver_Store_ch2);
288
        Pcint_SetCallback(pcint_id, pcint, &IrTransceiver_Store_ch2);
294
    }
289
    }
295
   
290
   
296
    if (channel < 3)
291
    if (channel < 3)
297
    {
292
    {
298
        /* Set port direction to input */
293
        /* Set port direction to input */
299
        *ddr &= ~(1 << nr);
294
        *ddr &= ~(1 << nr);
300
       
295
       
301
        irRxChannel[channel].rxbuf = buffer;
296
        drvIrRxChannel[channel].rxbuf = buffer;
302
        irRxChannel[channel].rxlen = 0;
297
        drvIrRxChannel[channel].rxlen = 0;
303
        irRxChannel[channel].storeEnable = FALSE;
298
        drvIrRxChannel[channel].storeEnable = FALSE;
304
        irRxChannel[channel].timeoutEnable = FALSE;
299
        drvIrRxChannel[channel].timeoutEnable = FALSE;
305
        irRxChannel[channel].callback = callback;
300
        drvIrRxChannel[channel].callback = callback;
-
 
301
        drvIrRxChannel[channel].enable = TRUE;
-
 
302
    }
-
 
303
}
-
 
304
 
-
 
305
/* call this function like this:
-
 
306
    IrTransceiver_DeInit_TX_Channel(channelnumber, pcint-id, GPIO_D6);
-
 
307
*/
-
 
308
 
-
 
309
void IrTransceiver_DeInit_TX_Channel(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)
-
 
310
{
-
 
311
    /* Deactivate interrupt */
-
 
312
    Pcint_SetCallback(pcint_id, pcint, 0);
-
 
313
   
-
 
314
    if (channel < 3)
-
 
315
    {
-
 
316
        /* Deactivate channel */
-
 
317
        drvIrRxChannel[channel].enable = FALSE;
-
 
318
        drvIrRxChannel[channel].rxlen = 0;
-
 
319
        drvIrRxChannel[channel].storeEnable = FALSE;
-
 
320
        drvIrRxChannel[channel].timeoutEnable = FALSE;
-
 
321
        drvIrRxChannel[channel].callback = 0;
-
 
322
    }
-
 
323
}
-
 
324
 
-
 
325
uint8_t IrTransceiver_GetStoreEnable(uint8_t channel)
-
 
326
{
-
 
327
    return drvIrRxChannel[channel].storeEnable;
-
 
328
}
-
 
329
 
-
 
330
void IrTransceiver_Disable(uint8_t channel)
-
 
331
{
-
 
332
    if (channel < 3)
-
 
333
    {
-
 
334
        /* Soft disable channel */
-
 
335
        drvIrRxChannel[channel].enable = FALSE;
-
 
336
    }
-
 
337
}
-
 
338
void IrTransceiver_Enable(uint8_t channel)
-
 
339
{
-
 
340
    if (channel < 3)
-
 
341
    {
-
 
342
        /* Soft enable channel */
-
 
343
        drvIrRxChannel[channel].enable = TRUE;
-
 
344
    }
-
 
345
}
-
 
346
void IrTransceiver_Reset(uint8_t channel)
-
 
347
{
-
 
348
    if (channel < 3)
306
       
349
    {
-
 
350
        /* Reset channel */
-
 
351
        drvIrRxChannel[channel].rxlen = 0;
-
 
352
        drvIrRxChannel[channel].storeEnable = FALSE;
-
 
353
        drvIrRxChannel[channel].timeoutEnable = FALSE;
307
    }
354
    }
308
}
355
}
-
 
356
 
309
#endif
357
#endif
310
 
358
 
311
/*
359
/*
312
void IrTransceiver_Init_RX_Channel(uint8_t channel, uint16_t *buffer, irCallback_t callback, volatile uint8_t* port, volatile uint8_t* pin, volatile uint8_t* ddr,uint8_t nr, uint8_t pcint)
360
void IrTransceiver_Init_RX_Channel(uint8_t channel, uint16_t *buffer, irCallback_t callback, volatile uint8_t* port, volatile uint8_t* pin, volatile uint8_t* ddr,uint8_t nr, uint8_t pcint)
313
{
361
{
Line 315... Line 363...
315
}
363
}
316
*/
364
*/
317
 
365
 
318
void IrTransceiver_Init(void)
366
void IrTransceiver_Init(void)
319
{
367
{
-
 
368
    for (uint8_t i = 0; i < 3; i++)
-
 
369
    {
-
 
370
        drvIrRxChannel[i].storeEnable = FALSE;
-
 
371
        drvIrRxChannel[i].timeoutEnable = FALSE;
-
 
372
        drvIrRxChannel[i].rxlen = 0;
-
 
373
    }
-
 
374
 
320
    IR_TIMER_INIT();
375
    IR_TIMER_INIT();
321
       
376
       
322
#if IR_TX_ENABLE==1
377
#if IR_TX_ENABLE==1
323
    /* Set up transmitter */
378
    /* Set up transmitter */
324
    IR_T_DDR |= (1<<IR_T_BIT);
379
    IR_T_DDR |= (1<<IR_T_BIT);