Subversion Repositories HomeAutomation

Rev

Rev 317 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 317 Rev 320
1
/**
1
/**
2
 * CanBlinds.
2
 * CanBlinds.
3
 * Takes incomming packages and adjusts PWM output.
3
 * Takes incomming packages and adjusts PWM output.
4
 * Input: -128 to +127
4
 * Input: -128 to +127
5
 * Position msg: <byte0 BLINDS_CMD> <byte1 position> <byte2 servo number>
5
 * Position msg: <byte0 BLINDS_CMD> <byte1 position> <byte2 servo number>
6
 * Turning msg: <byte0 START/STOP> <byte 1 direction> <byte2 servo number>
6
 * Turning msg: <byte0 START/STOP> <byte 1 direction> <byte2 servo number>
7
 *
7
 *
8
 * @date    2007-01-01
8
 * @date    2007-01-01
9
 * @author  Erik Larsson
9
 * @author  Erik Larsson
10
 *
10
 *
11
 */
11
 */
12
 
12
 
13
//#define TWO_BUTTON_MODE /* If using two (or just one but nothing more) auxiliary buttons */
13
//#define TWO_BUTTON_MODE /* If using two (or just one but nothing more) auxiliary buttons */
14
 
14
 
15
/*-----------------------------------------------------------------------------
15
/*-----------------------------------------------------------------------------
16
 * Includes
16
 * Includes
17
 *---------------------------------------------------------------------------*/
17
 *---------------------------------------------------------------------------*/
18
/* system files */
18
/* system files */
19
#include <avr/io.h>
19
#include <avr/io.h>
20
#include <avr/interrupt.h>
20
#include <avr/interrupt.h>
21
#include <avr/wdt.h>
-
 
22
#include <stdio.h>
21
#include <stdio.h>
23
/* lib files */
22
/* lib files */
24
#include <bios.h>
23
#include <bios.h>
25
#include <tc1047.h>
24
#include <tc1047.h>
26
#include <rc_servo.h>
25
#include <rc_servo.h>
27
 
26
 
28
#include <eqlazer_funcdefs.h>
27
#include <eqlazer_funcdefs.h>
29
 
28
 
30
/* defines */
29
/* defines */
31
#define NUMBER_OF_RCS 1
-
 
32
#define NODE_ID     0x03L // FIXME ändras för varje nod
30
#define NODE_ID     0x03L // FIXME ändras för varje nod
33
#define GROUP_ID    0x01L // ^
31
#define GROUP_ID    0x01L // ^
34
 
32
 
35
#define FAILSAFE_MODE       0x0F
33
#define FAILSAFE_MODE       0x0F
36
#define FAILSAFE_TRESHOLD   60  /* Degrees celcius when nodeBlinds goes into failsafe mode */
34
#define FAILSAFE_TRESHOLD   60  /* Degrees celcius when nodeBlinds goes into failsafe mode */
37
 
35
 
38
#define BLINDS_CMD_ABS      0x01 /* Absolute position */
36
#define BLINDS_CMD_ABS      0x01 /* Absolute position */
39
#define BLINDS_CMD_REL      0x02 /* Relative position */
37
#define BLINDS_CMD_REL      0x02 /* Relative position */
40
#define BLINDS_CMD_START    0x03 /* Start turning RC-servo */
38
#define BLINDS_CMD_START    0x03 /* Start turning RC-servo */
41
#define BLINDS_CMD_STOP     0x04 /* Stop turning RC-servo */
39
#define BLINDS_CMD_STOP     0x04 /* Stop turning RC-servo */
42
#define BLINDS_CMD_RESET    0x05
40
#define BLINDS_CMD_RESET    0x05
43
#define BLINDS_CMD_STATUS   0x06
41
#define BLINDS_CMD_STATUS   0x06
44
 
42
 
45
#define BLINDS_TURN_STOP    0x00
43
#define BLINDS_TURN_STOP    0x00
46
#define BLINDS_TURN_LEFT    0x01
44
#define BLINDS_TURN_LEFT    0x01
47
#define BLINDS_TURN_RIGHT   0x02
45
#define BLINDS_TURN_RIGHT   0x02
48
 
46
 
49
#define STEPS_PER_TURN_PERIOD   10 /* number of steps for each adjustment */
47
#define STEPS_PER_TURN_PERIOD   10 /* number of steps for each adjustment */
50
#define TURN_PERIOD             100 /* ms */
48
#define TURN_PERIOD             100 /* ms */
51
#define STATUS_SEND_PERIOD      10000 /* ms */
49
#define STATUS_SEND_PERIOD      5000 /* ms */
52
#define FAILSAFE_SEND_PERIOD    10000 /* ms */
50
#define FAILSAFE_SEND_PERIOD    10000 /* ms */
53
#define BOUNCE_TIME             10 /* ms */
51
#define BOUNCE_TIME             10 /* ms */
54
#define SERVO_FEED_TIME         2000 /* ms */
52
#define SERVO_FEED_TIME         2000 /* ms */
55
#define BUTTON1                 1
53
#define BUTTON1                 1
56
#define BUTTON2                 2
54
#define BUTTON2                 2
57
 
55
 
58
#define TRUE 1
56
#define TRUE 1
59
#define FALSE !TRUE
57
#define FALSE !TRUE
60
 
58
 
61
/*-------------------------------------------------------------------------
59
/*-------------------------------------------------------------------------
62
 * Global variables
60
 * Global variables
63
 * -----------------------------------------------------------------------*/
61
 * -----------------------------------------------------------------------*/
64
/*#if defined(TWO_BUTTON_MODE)
62
/*#if defined(TWO_BUTTON_MODE)
65
Can_Message_t txMsg_Button;
63
Can_Message_t txMsg_Button;
66
#endif*/
64
#endif*/
67
 
65
 
68
uint8_t msg_received = FALSE;
66
uint8_t msg_received = FALSE;
69
 
67
 
70
Can_Message_t txMsg;
68
Can_Message_t txMsg;
71
Can_Message_t rxMsg;
69
Can_Message_t rxMsg;
72
 
70
 
73
/*----------------------------------------------------------------------------
71
/*----------------------------------------------------------------------------
74
 * Functions
72
 * Functions
75
 * -------------------------------------------------------------------------*/
73
 * -------------------------------------------------------------------------*/
76
void blindsFailsafe();
74
void blindsFailsafe();
77
 
75
 
78
/* Takes care about incoming messages and parses them if this node is adressed */
76
/* Takes care about incoming messages and parses them if this node is adressed */
79
void can_receive(Can_Message_t *msg){
77
void can_receive(Can_Message_t *msg){
80
    uint32_t act;
78
    uint32_t act;
81
    uint8_t m, act_type, group, node;
79
    uint8_t m, act_type, group, node;
82
    if( ((msg->Id & CLASS_MASK) >> CLASS_MASK_BITS) == CLASS_ACT ){
80
    if( ((msg->Id & CLASS_MASK) >> CLASS_MASK_BITS) == CLASS_ACT ){
83
        /* Parse message */
81
        /* Parse message */
84
        act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
82
        act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
85
        act_type = (act & ACT_TYPE_MASK) >> ACT_TYPE_BITS;
83
        act_type = (act & ACT_TYPE_MASK) >> ACT_TYPE_BITS;
86
        group = (act & ACT_GROUP_MASK) >> ACT_GROUP_BITS;
84
        group = (act & ACT_GROUP_MASK) >> ACT_GROUP_BITS;
87
        node = (act & ACT_NODE_MASK) >> ACT_NODE_BITS;
85
        node = (act & ACT_NODE_MASK) >> ACT_NODE_BITS;
88
 
86
 
89
        /* Check if it is command to control this servo */
87
        /* Check if it is command to control this servo */
90
        if(act_type == ACT_TYPE_SERVO){
88
        if(act_type == ACT_TYPE_SERVO){
91
            if(group == GROUP_ID || node == NODE_ID){
89
            if(group == GROUP_ID || node == NODE_ID){
92
                for(m=0;m<msg->DataLength;m++){
90
                for(m=0;m<msg->DataLength;m++){
93
                    rxMsg.Data.bytes[m] = msg->Data.bytes[m];
91
                    rxMsg.Data.bytes[m] = msg->Data.bytes[m];
94
                }
92
                }
95
                msg_received = TRUE;
93
                msg_received = TRUE;
96
            }
94
            }
97
        }
95
        }
98
    }
96
    }
99
}
97
}
100
 
98
 
101
/*----------------------------------------------------------------------------
99
/*----------------------------------------------------------------------------
102
 * Interrupt routines
100
 * Interrupt routines
103
 * -------------------------------------------------------------------------*/
101
 * -------------------------------------------------------------------------*/
104
#if defined(TWO_BUTTON_MODE)
102
#if defined(TWO_BUTTON_MODE)
105
#error two button mode is still untested
103
#error two button mode is still untested
106
ISR( PCINT2_vect )
104
ISR( PCINT2_vect )
107
{
105
{
108
    /*
106
    /*
109
     * Auxiliary button pressed and released
107
     * Auxiliary button pressed and released
110
     * Check time between press and release to eliminate bounces
108
     * Check time between press and release to eliminate bounces
111
     */
109
     */
112
    static uint32_t buttonTime[2];
110
    static uint32_t buttonTime[2];
113
 
111
 
114
    txMsg_Button.RemoteFlag = 0;
112
    txMsg_Button.RemoteFlag = 0;
115
    txMsg_Button.ExtendedFlag = 1;
113
    txMsg_Button.ExtendedFlag = 1;
116
 
114
 
117
    if( (PIND & (1<<PD1)) == 0){
115
    if( (PIND & (1<<PD1)) == 0){
118
        /* Button pressed */
116
        /* Button pressed */
119
        buttonTime[0] = Timebase_CurrentTime();
117
        buttonTime[0] = Timebase_CurrentTime();
120
    }else if( (PIND & (1<<PD1)) == 1){
118
    }else if( (PIND & (1<<PD1)) == 1){
121
        if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
119
        if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
122
            /* No bounce, send message */
120
            /* No bounce, send message */
123
            txMsg_Button.Id = BUTTON_ID;
121
            txMsg_Button.Id = BUTTON_ID;
124
            txMsg_Button.DataLength = 1;
122
            txMsg_Button.DataLength = 1;
125
            txMsg_Button.Data.bytes[0] = BUTTON1;
123
            txMsg_Button.Data.bytes[0] = BUTTON1;
126
            return;
124
            return;
127
        }else{
125
        }else{
128
            /* Just bounces, ignore it */
126
            /* Just bounces, ignore it */
129
            return;
127
            return;
130
        }
128
        }
131
    }
129
    }
132
    if( (PIND & (1<<PD2)) == 0){
130
    if( (PIND & (1<<PD2)) == 0){
133
        /* Button pressed */
131
        /* Button pressed */
134
        buttonTime[1] = Timebase_CurrentTime();
132
        buttonTime[1] = Timebase_CurrentTime();
135
    }else if( (PIND & (1<<PD2)) == 1){
133
    }else if( (PIND & (1<<PD2)) == 1){
136
        if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
134
        if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
137
            /* No bounce, send message */
135
            /* No bounce, send message */
138
            txMsg_Button.Id = BUTTON_ID;
136
            txMsg_Button.Id = BUTTON_ID;
139
            txMsg_Button.DataLength = 1;
137
            txMsg_Button.DataLength = 1;
140
            txMsg_Button.Data.bytes[0] = BUTTON2;
138
            txMsg_Button.Data.bytes[0] = BUTTON2;
141
            return;
139
            return;
142
        }else{
140
        }else{
143
            /* Just bounces, ignore it */
141
            /* Just bounces, ignore it */
144
            return;
142
            return;
145
        }
143
        }
146
    }
144
    }
147
}
145
}
148
#endif
146
#endif
149
 
147
 
150
/*-----------------------------------------------------------------------------
148
/*-----------------------------------------------------------------------------
151
 * Main Program
149
 * Main Program
152
 *---------------------------------------------------------------------------*/
150
 *---------------------------------------------------------------------------*/
153
int main(void) {
151
int main(void) {
154
 
152
 
155
    uint8_t //blindsStatus, /* Position (-128 to 127) */
153
    uint8_t //blindsStatus, /* Position (-128 to 127) */
156
            servoToTurn,
154
            servoToTurn,
157
            turnDirection = BLINDS_TURN_STOP; /* Specifies direction to turn or stopped */
155
            turnDirection = BLINDS_TURN_STOP; /* Specifies direction to turn or stopped */
158
    uint32_t boardTemperature = 0;
156
    uint32_t boardTemperature = 0;
159
    uint32_t timeStamp = 0, timeStampTurn = 0, servoFeed_timeStamp = 0;
157
    uint32_t timeStamp = 0, timeStampTurn = 0, servoFeed_timeStamp = 0;
160
 
158
 
-
 
159
    sei();
161
    adcTemperatureInit();
160
    adcTemperatureInit();
162
    rcServoInit();
161
    rcServoInit();
163
 
162
 
164
#if defined(TWO_BUTTON_MODE)
163
#if defined(TWO_BUTTON_MODE)
165
    /*
164
    /*
166
     * Initialize buttons
165
     * Initialize buttons
167
     * It is possible to use ie. sensors instead
166
     * It is possible to use ie. sensors instead
168
     * but then change this
167
     * but then change this
169
     */
168
     */
170
    /* Set as input and enable pull-up */
169
    /* Set as input and enable pull-up */
171
    DDRD &= ~( (1<<DDD1)|(1<<DDD2) );
170
    DDRD &= ~( (1<<DDD1)|(1<<DDD2) );
172
    PORTD |= (1<<PD1)|(1<<PD2);
171
    PORTD |= (1<<PD1)|(1<<PD2);
173
 
172
 
174
    /* Enable IO-pin interrupt */
173
    /* Enable IO-pin interrupt */
175
    PCICR |= (1<<PCIE2);
174
    PCICR |= (1<<PCIE2);
176
    /* Unmask PD1 and PD2 */
175
    /* Unmask PD1 and PD2 */
177
    PCMSK2 |= (1<<PCINT16) | (1<<PCINT17);
176
    PCMSK2 |= (1<<PCINT16) | (1<<PCINT17);
178
#endif
177
#endif
179
    /* Set output and turn off the servo current feed */
178
    /* Set output and turn off the servo current feed */
180
    DDRC |= (1<<DDC0);
179
    DDRC |= (1<<DDC0);
181
    PORTC &= ~(1<<PC0);
180
    PORTC &= ~(1<<PC0);
182
 
181
 
183
    sei();
182
//  sei();
184
 
183
 
185
    txMsg.RemoteFlag = 0;
184
    txMsg.RemoteFlag = 0;
186
    txMsg.ExtendedFlag = 1;
185
    txMsg.ExtendedFlag = 1;
187
    txMsg.Id = (CLASS_SNS << CLASS_MASK_BITS)|(SNS_ACT_STATUS_SERVO << TYPE_MASK_BITS)|(NODE_ID << SID_MASK_BITS);
186
    txMsg.Id = (CLASS_SNS << CLASS_MASK_BITS)|(SNS_ACT_STATUS_SERVO << TYPE_MASK_BITS)|(NODE_ID << SID_MASK_BITS);
188
 
187
 
189
    /* Set up callback for CAN messages */
188
    /* Set up callback for CAN messages */
190
    bios->can_callback = &can_receive;
189
    bios->can_callback = &can_receive;
191
 
190
 
192
    /* main loop */
191
    /* main loop */
193
    while (1) {
192
    while (1) {
194
        /* check if any messages have been received */
193
        /* check if any messages have been received */
195
        if(msg_received){
194
        if(msg_received){
196
            /* This node that control a servo is adressed */
195
            /* This node that control a servo is adressed */
197
 
196
 
198
            if( rxMsg.Data.bytes[0] == BLINDS_CMD_ABS ){
197
            if( rxMsg.Data.bytes[0] == BLINDS_CMD_ABS ){
199
                /* Set absolute position to servo */
198
                /* Set absolute position to servo */
200
                setPosition( rxMsg.Data.bytes[1], rxMsg.Data.bytes[2] );
199
                setPosition( rxMsg.Data.bytes[1], rxMsg.Data.bytes[2] );
201
                timeStampTurn = bios->timebase_get();
200
                timeStampTurn = bios->timebase_get();
202
 
201
 
203
            }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_REL){
202
            }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_REL){
204
                /* Set relative position to servo */
203
                /* Set relative position to servo */
205
                alterPosition( rxMsg.Data.bytes[1], rxMsg.Data.bytes[2] );
204
                alterPosition( rxMsg.Data.bytes[1], rxMsg.Data.bytes[2] );
206
                timeStampTurn = bios->timebase_get();
205
                timeStampTurn = bios->timebase_get();
207
 
206
 
208
            }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_START ){
207
            }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_START ){
209
                /* Start turning the servo */
208
                /* Start turning the servo */
210
                turnDirection = rxMsg.Data.bytes[1];
209
                turnDirection = rxMsg.Data.bytes[1];
211
                servoToTurn = rxMsg.Data.bytes[2];
210
                servoToTurn = rxMsg.Data.bytes[2];
212
                timeStampTurn = bios->timebase_get();
211
                timeStampTurn = bios->timebase_get();
213
 
212
 
214
            }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STOP ){
213
            }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STOP ){
215
                /* Stop turning */
214
                /* Stop turning */
216
                turnDirection = BLINDS_TURN_STOP;
215
                turnDirection = BLINDS_TURN_STOP;
217
 
216
 
218
            }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STATUS){
217
            }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STATUS){
219
                /* Send blinds status to CAN */
218
                /* Send blinds status to CAN */
220
                boardTemperature = getTC1047temperature();
219
                boardTemperature = getTC1047temperature();
221
 
220
 
222
                if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
221
                if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
223
                    blindsFailsafe();
222
                    blindsFailsafe();
224
                }else{
223
                }else{
225
                    txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
224
                    txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
226
                    txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
225
                    txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
227
                    txMsg.Data.bytes[2] = 0x00;
226
                    txMsg.Data.bytes[2] = 0x00;
228
#if NUMBER_OF_RCS >0
227
#if NUMBER_OF_RCS >0
229
                    txMsg.Data.bytes[3] = getPosition(1);
228
                    txMsg.Data.bytes[3] = getPosition(1);
230
#endif
229
#endif
231
#if NUMBER_OF_RCS >1
230
#if NUMBER_OF_RCS >1
232
                    txMsg.Data.bytes[4] = getPosition(2);
231
                    txMsg.Data.bytes[4] = getPosition(2);
233
#endif
232
#endif
234
#if NUMBER_OF_RCS >2
233
#if NUMBER_OF_RCS >2
235
                    txMsg.Data.bytes[5] = getPosition(3);
234
                    txMsg.Data.bytes[5] = getPosition(3);
236
#endif
235
#endif
237
                    txMsg.DataLength = NUMBER_OF_RCS+3;
236
                    txMsg.DataLength = NUMBER_OF_RCS+3;
238
                    bios->can_send(&txMsg);
237
                    bios->can_send(&txMsg);
239
                    }
238
                    }
240
                }
239
                }
241
                msg_received = FALSE;
240
                msg_received = FALSE;
242
        }
241
        }
243
 
242
 
244
        if( bios->timebase_get() - timeStamp  >= STATUS_SEND_PERIOD ){
243
        if( (bios->timebase_get() - timeStamp)  >= STATUS_SEND_PERIOD ){
245
            timeStamp = bios->timebase_get();
244
            timeStamp = bios->timebase_get();
246
            /* Send blinds status to CAN */
245
            /* Send blinds status to CAN */
247
 
246
 
248
            boardTemperature = getTC1047temperature();
247
            boardTemperature = getTC1047temperature();
249
 
248
 
250
            if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
249
            if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
251
                blindsFailsafe();
250
                blindsFailsafe();
252
            }else{
251
            }else{
253
                txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
252
                txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
254
                txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
253
                txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
255
                txMsg.Data.bytes[2] = 0x00;
254
                txMsg.Data.bytes[2] = 0x00;
256
#if NUMBER_OF_RCS >0
255
#if NUMBER_OF_RCS >0
257
                txMsg.Data.bytes[3] = getPosition(1);
256
                txMsg.Data.bytes[3] = getPosition(1);
258
#endif
257
#endif
259
#if NUMBER_OF_RCS >1
258
#if NUMBER_OF_RCS >1
260
                txMsg.Data.bytes[4] = getPosition(2);
259
                txMsg.Data.bytes[4] = getPosition(2);
261
#endif
260
#endif
262
#if NUMBER_OF_RCS >2
261
#if NUMBER_OF_RCS >2
263
                txMsg.Data.bytes[5] = getPosition(3);
262
                txMsg.Data.bytes[5] = getPosition(3);
264
#endif
263
#endif
265
                txMsg.DataLength = NUMBER_OF_RCS+3;
264
                txMsg.DataLength = NUMBER_OF_RCS+3;
266
 
265
 
267
                bios->can_send(&txMsg);
266
                bios->can_send(&txMsg);
268
            }
267
            }
269
        }
268
        }
270
        /* If start turning servo */
269
        /* If start turning servo */
271
        if( turnDirection ){
270
        if( turnDirection ){
272
            if( bios->timebase_get() - timeStampTurn >= TURN_PERIOD ){
271
            if( bios->timebase_get() - timeStampTurn >= TURN_PERIOD ){
273
                timeStampTurn = bios->timebase_get();
272
                timeStampTurn = bios->timebase_get();
274
                /* Clockwise or counterclockwise? */
273
                /* Clockwise or counterclockwise? */
275
                if( turnDirection == BLINDS_TURN_LEFT ){
274
                if( turnDirection == BLINDS_TURN_LEFT ){
276
                    alterPosition( -STEPS_PER_TURN_PERIOD , servoToTurn);
275
                    alterPosition( -STEPS_PER_TURN_PERIOD , servoToTurn);
277
                }else if( turnDirection == BLINDS_TURN_RIGHT ){
276
                }else if( turnDirection == BLINDS_TURN_RIGHT ){
278
                    alterPosition( STEPS_PER_TURN_PERIOD , servoToTurn);
277
                    alterPosition( STEPS_PER_TURN_PERIOD , servoToTurn);
279
                }
278
                }
280
            }
279
            }
281
        }
280
        }
282
        /* Turn off the servo current feed */
281
        /* Turn off the servo current feed */
283
        if( bios->timebase_get() - servoFeed_timeStamp >= SERVO_FEED_TIME ){
282
        if( bios->timebase_get() - servoFeed_timeStamp >= SERVO_FEED_TIME ){
284
            PORTC &= ~(1<<PC0);
283
            PORTC &= ~(1<<PC0);
285
        }else{
284
        }else{
286
            PORTC |= (1<<PC0);
285
            PORTC |= (1<<PC0);
287
        }
286
        }
288
    }
287
    }
289
    return 0;
288
    return 0;
290
}
289
}
291
 
290
 
292
void blindsFailsafe()
291
void blindsFailsafe()
293
{
292
{
294
    uint8_t relayStatus;
293
    uint8_t relayStatus;
295
    uint32_t boardTemperature = 0, timeStamp = 0;
294
    uint32_t boardTemperature = 0, timeStamp = 0;
296
 
295
 
297
    /* Turn of servo current feed */
296
    /* Turn of servo current feed */
298
    PORTC &= ~(1<<PC0);
297
    PORTC &= ~(1<<PC0);
299
 
298
 
300
 
299
 
301
    while(1){
300
    while(1){
302
        /* check if any messages have been received */
301
        /* check if any messages have been received */
303
        while(msg_received) {
302
        while(msg_received) {
304
            /* This relay is adressed*/
303
            /* This relay is adressed*/
305
            if(rxMsg.Data.bytes[0] == BLINDS_CMD_RESET ){
304
            if(rxMsg.Data.bytes[0] == BLINDS_CMD_RESET ){
306
                /* Return from failsafe mode */
305
                /* Return from failsafe mode */
307
                return;
306
                return;
308
            }
307
            }
309
        }
308
        }
310
 
309
 
311
        if( bios->timebase_get() - timeStamp >= FAILSAFE_SEND_PERIOD ){
310
        if( bios->timebase_get() - timeStamp >= FAILSAFE_SEND_PERIOD ){
312
            timeStamp = bios->timebase_get();
311
            timeStamp = bios->timebase_get();
313
            /* Send relay status to CAN */
312
            /* Send relay status to CAN */
314
            boardTemperature = getTC1047temperature();
313
            boardTemperature = getTC1047temperature();
315
 
314
 
316
            txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
315
            txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
317
            txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
316
            txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
318
            txMsg.Data.bytes[2] = FAILSAFE_MODE;
317
            txMsg.Data.bytes[2] = FAILSAFE_MODE;
319
#if NUMBER_OF_RCS >0
318
#if NUMBER_OF_RCS >0
320
            txMsg.Data.bytes[3] = getPosition(1);
319
            txMsg.Data.bytes[3] = getPosition(1);
321
#endif
320
#endif
322
#if NUMBER_OF_RCS >1
321
#if NUMBER_OF_RCS >1
323
            txMsg.Data.bytes[4] = getPosition(2);
322
            txMsg.Data.bytes[4] = getPosition(2);
324
#endif
323
#endif
325
#if NUMBER_OF_RCS >2
324
#if NUMBER_OF_RCS >2
326
            txMsg.Data.bytes[5] = getPosition(3);
325
            txMsg.Data.bytes[5] = getPosition(3);
327
#endif
326
#endif
328
            txMsg.DataLength = NUMBER_OF_RCS+3;
327
            txMsg.DataLength = NUMBER_OF_RCS+3;
329
 
328
 
330
            bios->can_send(&txMsg);
329
            bios->can_send(&txMsg);
331
        }
330
        }
332
    }
331
    }
333
}
332
}
334
 
333
 
335
 
334