Subversion Repositories HomeAutomation

Rev

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

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