Subversion Repositories HomeAutomation

Rev

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

Rev 1468 Rev 1470
Line 19... Line 19...
19
 
19
 
20
/*-----------------------------------------------------------------------------
20
/*-----------------------------------------------------------------------------
21
 * Globals
21
 * Globals
22
 *---------------------------------------------------------------------------*/
22
 *---------------------------------------------------------------------------*/
23
#if IR_RX_ENABLE==1
23
#if IR_RX_ENABLE==1
24
uint16_t *rxbuf;
-
 
25
uint8_t rxlen;
-
 
26
 
-
 
27
/*struct {
24
struct {
28
    uint8_t     dataReceived;
-
 
29
    uint16_t    timeout;
25
    uint16_t    timeout;
30
    uint8_t     timeoutEnable;
26
    uint8_t     timeoutEnable;
31
    uint16_t    *rxbuf;
27
    uint16_t    *rxbuf;
32
    uint8_t     rxlen;
28
    uint8_t     rxlen;
33
    uint8_t     storeEnable;
29
    uint8_t     storeEnable;
-
 
30
    irCallback_t callback;
34
} irRxChannel[3];
31
} irRxChannel[3];
35
*/
-
 
36
 
32
 
-
 
33
 
37
#endif
34
#endif
38
#if IR_TX_ENABLE==1
35
#if IR_TX_ENABLE==1
39
uint16_t *txbuf;
36
uint16_t *txbuf;
40
uint8_t txlen;
37
uint8_t txlen;
41
#endif
-
 
42
 
-
 
43
#if IR_TX_ENABLE==1
-
 
44
static uint8_t bufIndex;                            //selects the pulse width in buffer to send
38
static uint8_t bufIndex;                            //selects the pulse width in buffer to send
45
#endif
39
#endif
46
volatile uint8_t data_received;
-
 
-
 
40
 
47
volatile uint8_t data_transmitted;
41
volatile uint8_t data_transmitted;
48
//uint8_t detect_edge;
-
 
49
uint8_t store;
-
 
50
 
42
 
51
 
43
 
52
/*-----------------------------------------------------------------------------
44
/*-----------------------------------------------------------------------------
53
 * Prerequisites
45
 * Prerequisites
54
 *---------------------------------------------------------------------------*/
46
 *---------------------------------------------------------------------------*/
Line 143... Line 135...
143
 
135
 
144
#if IR_RX_ENABLE==1
136
#if IR_RX_ENABLE==1
145
//TODO: hur hantera detta i multi receiver
137
//TODO: hur hantera detta i multi receiver
146
//TODO: ha en array med tider och nån enableflagga för varje kanal
138
//TODO: ha en array med tider och nån enableflagga för varje kanal
147
//TODO: mot slutet av ISRen laddas nästa tid in...
139
//TODO: mot slutet av ISRen laddas nästa tid in...
-
 
140
 
-
 
141
/* When this timeout occurs a pulsetrain is complete */
148
ISR(IR_TIMEOUT_VECTOR)
142
ISR(IR_TIMEOUT_VECTOR)
149
{
143
{
-
 
144
 
-
 
145
    /* Find which channel timed out */
-
 
146
    uint16_t timeDiff = 0xffff;
150
    if (rxlen)
147
    uint8_t channel = 0;
-
 
148
    for (uint8_t i=0; i < 3; i++)
151
    {
149
    {
152
        /* Disable interrupts until the application has taken action on the
150
        if ((irRxChannel[channel].timeoutEnable) && (IR_TIMEOUT_REG-irRxChannel[i].timeout < timeDiff))
-
 
151
        {
153
         * current data and reenabled reception. */
152
            timeDiff = IR_TIMEOUT_REG-irRxChannel[i].timeout;
154
//      IR_MASK_CAPTURE();
153
            channel = i;
-
 
154
        }
-
 
155
    }
-
 
156
 
155
//      IR_MASK_TIMEOUT();
157
    /* If more than 3 flanks was recevied */
156
        PCMSK0 &= ~(1<<IR_TRANS_CH0_MASK);
158
    if (irRxChannel[channel].rxlen > 3)
157
 
159
    {
158
        /* Notify the application that a pulse train has been received. */
160
        /* Notify the application that a pulse train has been received. */
-
 
161
        irRxChannel[channel].callback(channel, irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen);
-
 
162
    }
-
 
163
 
-
 
164
    irRxChannel[channel].storeEnable = FALSE;
-
 
165
    irRxChannel[channel].timeoutEnable = FALSE;
-
 
166
 
159
        data_received = 1;
167
    IR_UNMASK_TIMEOUT();
-
 
168
   
-
 
169
//TODO: reset the timeout for next enabled channel
-
 
170
/*
-
 
171
    uint16_t nextTimeout = irRxChannel[channel].timeout;
-
 
172
    for (uint8_t i=0; i < 3; i++)
-
 
173
    {
-
 
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
//kanske inte är så noga, i värsta fall tar det 65ms extra
-
 
176
        if ((irRxChannel[channel].timeoutEnable) && (irRxChannel[i].timeout < nextTimeout))
-
 
177
        {
-
 
178
            nextTimeout = irRxChannel[i].timeout;
-
 
179
        }
160
    }
180
    }
161
    store = 0;
-
 
162
}
-
 
163
#endif
-
 
164
 
-
 
165
#if 0
-
 
166
 
-
 
167
//ISR(IR_CAPTURE_VECTOR)
181
    IR_MASK_TIMEOUT();
168
//TODO: skriv denna för multi receiver
182
    IR_TIMEOUT_REG = nextTimeout;
169
ISR(PCINT0_vect) {
-
 
170
//  uint8_t p;
-
 
171
    uint8_t rPinB=PINB;
-
 
172
    uint8_t rPinC=PINC;
-
 
173
    uint8_t rPinD=PIND;
-
 
174
   
-
 
175
    /* check if channel 0 pin was changed */
-
 
176
    if ((rPinB ^ gPinB)&(1<<IR_TRANS_CH0_MASK))
-
 
177
    {
183
*/
178
        IrTransceiver_Store(0);
-
 
179
    }
184
}
180
   
-
 
181
    gPinB=rPinB;
-
 
182
    gPinC=rPinC;
-
 
183
    gPinD=rPinD;
-
 
184
} /* ISR(PCINT0_vect) */
-
 
185
#endif
185
#endif
186
 
186
 
187
 
187
 
188
/*-----------------------------------------------------------------------------
188
/*-----------------------------------------------------------------------------
189
 * Private Functions
189
 * Private Functions
190
 *---------------------------------------------------------------------------*/
190
 *---------------------------------------------------------------------------*/
191
 
191
 
192
#if IR_RX_ENABLE==1
192
#if IR_RX_ENABLE==1
-
 
193
 
-
 
194
/* these wrapper functions are called from the pcint driver (callback) */
193
void IrTransceiver_Store_ch0(uint8_t id, uint8_t status)
195
void IrTransceiver_Store_ch0(uint8_t id, uint8_t status)
194
{
196
{
195
    IrTransceiver_Store(0);
197
    IrTransceiver_Store(0);
196
}
198
}
197
void IrTransceiver_Store_ch1(uint8_t id, uint8_t status)
199
void IrTransceiver_Store_ch1(uint8_t id, uint8_t status)
Line 217... Line 219...
217
     * width. */
219
     * width. */
218
    pulsewidth = time - prev_time;
220
    pulsewidth = time - prev_time;
219
    prev_time = time;
221
    prev_time = time;
220
   
222
   
221
    /* Set the timeout. */
223
    /* Set the timeout. */
222
    IR_TIMEOUT_REG = time + IR_MAX_PULSE_WIDTH;
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;
223
   
237
   
224
    if (store)
238
    if (irRxChannel[channel].storeEnable)
225
    {
239
    {
226
        /* Store the measurement. */
240
        /* Store the measurement. */
227
        rxbuf[rxlen++] = pulsewidth;
241
        irRxChannel[channel].rxbuf[irRxChannel[channel].rxlen++] = pulsewidth;
228
        //*(rxbuf+rxlen++) = pulsewidth;
-
 
-
 
242
 
229
        /* Disable future measurements if we've filled the buffer. */
243
        /* Disable future measurements if we've filled the buffer. */
230
        //TODO: What to do in multi recevier?
244
        //TODO: What to do in multi recevier?
231
        //TODO: Report overflow to application
245
        //TODO: Report overflow to application
232
        if (rxlen == MAX_NR_TIMES)
246
        if (irRxChannel[channel].rxlen == MAX_NR_TIMES)
233
        {
247
        {
-
 
248
            irRxChannel[channel].rxlen = MAX_NR_TIMES-1;
234
            //IR_MASK_CAPTURE();
249
            //IR_MASK_CAPTURE();
235
        }
250
        }
236
    }
251
    }
237
    else
252
    else
238
    {
253
    {
239
        /* The first edge of the pulse train has been detected. Enable the
254
        /* The first edge of the pulse train has been detected. Enable the
240
         * storage of the following pulsewidths. */
255
         * storage of the following pulsewidths. */
-
 
256
        irRxChannel[channel].storeEnable = TRUE;
241
        store = 1;
257
        irRxChannel[channel].rxlen = 0;
242
        /* Enable timeout interrupt for detection of the end of the pulse
258
        /* Enable timeout interrupt for detection of the end of the pulse train. */
243
         * train. */
-
 
244
        IR_UNMASK_TIMEOUT();
259
        IR_UNMASK_TIMEOUT();
245
 
260
 
246
        //TODO: if buffer resource coordinator is implemented this is where a buffer should be assinged to this channel
261
        //TODO: if buffer resource coordinator is implemented this is where a buffer should be assinged to this channel
247
    }
262
    }
248
}
263
}
249
#endif
264
#endif
250
 
265
 
251
 
266
 
252
/*-----------------------------------------------------------------------------
267
/*-----------------------------------------------------------------------------
253
 * Public Functions
268
 * Public Functions
254
 *---------------------------------------------------------------------------*/
269
 *---------------------------------------------------------------------------*/
255
 
270
 
Line 260... Line 275...
260
    also call with IO port to use
275
    also call with IO port to use
261
   
276
   
262
    function to deactivate channel may later be needed
277
    function to deactivate channel may later be needed
263
*/
278
*/
264
 
279
 
-
 
280
#if IR_RX_ENABLE==1
265
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)
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)
266
{
282
{
267
    if (channel == 0)
283
    if (channel == 0)
268
    {
284
    {
269
        Pcint_SetCallback(uint8_t pcint_id, uint8_t pcint, &IrTransceiver_Store_ch0);
285
        Pcint_SetCallback(uint8_t pcint_id, uint8_t pcint, &IrTransceiver_Store_ch0);
270
    }
286
    }
271
    else if (channel == 1)
287
    else if (channel == 1)
272
    {
288
    {
273
        Pcint_SetCallback(uint8_t pcint_id, uint8_t pcint, &IrTransceiver_Store_ch1);
289
        Pcint_SetCallback(uint8_t pcint_id, uint8_t pcint, &IrTransceiver_Store_ch1);
274
    }
290
    }
275
    else if (channel == 2)
291
    else if (channel == 2)
276
    {
292
    {
277
        Pcint_SetCallback(uint8_t pcint_id, uint8_t pcint, &IrTransceiver_Store_ch2);
293
        Pcint_SetCallback(uint8_t pcint_id, uint8_t pcint, &IrTransceiver_Store_ch2);
-
 
294
    }
-
 
295
   
-
 
296
    if (channel < 3)
-
 
297
    {
-
 
298
        /* Set port direction to input */
-
 
299
        *ddr &= ~(1 << nr);
-
 
300
       
-
 
301
        irRxChannel[channel].rxbuf = buffer;
-
 
302
        irRxChannel[channel].rxlen = 0;
-
 
303
        irRxChannel[channel].storeEnable = FALSE;
-
 
304
        irRxChannel[channel].timeoutEnable = FALSE;
-
 
305
        irRxChannel[channel].callback = callback;
-
 
306
       
278
    }
307
    }
279
}
308
}
-
 
309
#endif
280
 
310
 
281
/*
311
/*
282
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)
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)
283
{
313
{
284
   
314
   
Line 286... Line 316...
286
*/
316
*/
287
 
317
 
288
void IrTransceiver_Init(void)
318
void IrTransceiver_Init(void)
289
{
319
{
290
    IR_TIMER_INIT();
320
    IR_TIMER_INIT();
291
   
-
 
292
#if IR_RX_ENABLE==1
-
 
293
    /* Set up receiver */
-
 
294
    //IR_TIMEOUT_REG = IR_MAX_PULSE_WIDTH;
-
 
295
    IR_R_DDR &= ~(1<<IR_R_BIT);
-
 
296
    //DDRC |= (1<<PC5);
-
 
297
#endif
-
 
298
   
321
       
299
#if IR_TX_ENABLE==1
322
#if IR_TX_ENABLE==1
300
    /* Set up transmitter */
323
    /* Set up transmitter */
301
    IR_T_DDR |= (1<<IR_T_BIT);
324
    IR_T_DDR |= (1<<IR_T_BIT);
302
    #if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
325
    #if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
303
    TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(1<<WGM01)|(0<<WGM00);
326
    TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(1<<WGM01)|(0<<WGM00);
304
    TCCR0B = (0<<WGM02)|(1<<CS00)|(0<<CS01)|(0<<CS02);
327
    TCCR0B = (0<<WGM02)|(1<<CS00)|(0<<CS01)|(0<<CS02);
305
    #endif
328
    #endif
306
   
329
   
307
#if IR_TX_ACTIVE_LOW==1
330
#if IR_TX_ACTIVE_LOW==1
308
    /* when pwm is disconnected from port (during low) the port should output 5V */
331
    /* when pwm is disconnected from port (during low) the port should output 5V */
309
    IR_T_PORT |= (1<<IR_T_BIT);
332
    IR_T_PORT |= (1<<IR_T_BIT);
310
#else
333
#else
311
    /* when pwm is disconnected from port (during low) the port should output 0V */
334
    /* when pwm is disconnected from port (during low) the port should output 0V */
312
    IR_T_PORT &= ~(1<<IR_T_BIT);
335
    IR_T_PORT &= ~(1<<IR_T_BIT);
313
#endif
336
#endif
314
 
-
 
315
#endif
-
 
316
 
-
 
317
}
-
 
318
 
-
 
319
void IrTransceiver_Receive_Start(uint16_t *buffer)
-
 
320
{
-
 
321
#if IR_RX_ENABLE==1
-
 
322
     /* Setup buffer and arm the edge detection. */
-
 
323
    rxbuf = buffer;
-
 
324
    rxlen = 0;
-
 
325
    data_received = 0;
-
 
326
    store = 0;
-
 
327
#if (IR_RX_ACTIVE_LOW == 1)
-
 
328
    //IR_CAPTURE_FALLING();
-
 
329
    //detect_edge = 0;
-
 
330
#else
-
 
331
    //IR_CAPTURE_RISING();
-
 
332
    //detect_edge = 1;
-
 
333
#endif
-
 
334
    //IR_UNMASK_CAPTURE();
-
 
335
 
-
 
336
    gPinB=PINB;
-
 
337
    gPinC=PINC;
-
 
338
    gPinD=PIND;
-
 
339
    PCIFR=(1<<PCIF0|1<<PCIF1|1<<PCIF2); /* clear any pending interrupt before enabling interrupts */
-
 
340
//  PCICR|=(1<<PCIE0|1<<PCIE1|1<<PCIE2);    /* enable interrupt for PCINT0-2 */
-
 
341
    PCICR|=(1<<PCIE0);  /* enable interrupt for PCINT0 */
-
 
342
    PCMSK0 |= (1<<IR_TRANS_CH0_MASK);
-
 
343
//  PCMSK1 |= (1<<pcints[pcint_id].pcintBit%8);
-
 
344
//  PCMSK2 |= (1<<pcints[pcint_id].pcintBit%8);
-
 
345
#endif
-
 
346
 
-
 
347
}
-
 
348
 
337
 
349
uint8_t IrTransceiver_Receive_Poll(uint8_t *len)
-
 
350
{
-
 
351
#if IR_RX_ENABLE==1
-
 
352
    *len = rxlen;
-
 
353
    if (data_received)
-
 
354
    {
-
 
355
        return IR_OK;
-
 
356
    }
-
 
357
    else if (rxlen > 0)
-
 
358
    {
-
 
359
        return IR_NOT_FINISHED;
-
 
360
    } else {
-
 
361
        return IR_NO_DATA;
-
 
362
    }
-
 
363
#else
-
 
364
    return 0;
-
 
365
#endif
338
#endif
-
 
339
 
366
}
340
}
367
 
341
 
368
uint8_t IrTransceiver_Transmit_Poll(void) {
342
uint8_t IrTransceiver_Transmit_Poll(void) {
369
#if IR_TX_ENABLE==1
343
#if IR_TX_ENABLE==1
370
    if (data_transmitted == 0) {
344
    if (data_transmitted == 0) {