Subversion Repositories HomeAutomation

Rev

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

Rev 354 Rev 360
Line 20... Line 20...
20
 *---------------------------------------------------------------------------*/
20
 *---------------------------------------------------------------------------*/
21
/* system files */
21
/* system files */
22
#include <avr/io.h>
22
#include <avr/io.h>
23
#include <avr/interrupt.h>
23
#include <avr/interrupt.h>
24
#include <stdio.h>
24
#include <stdio.h>
25
#include <avr/wdt.h>
-
 
26
/* lib files */
25
/* lib files */
27
#include <bios.h>
26
#include <bios.h>
28
#include <tc1047.h>
27
#include <tc1047.h>
29
#include <funcdefs.h>
28
#include <funcdefs.h>
30
 
29
 
31
/* defines */
30
/* defines */
32
#define GROUP_ID        0x01UL
31
#define GROUP_ID        0x01UL
33
 
32
 
34
#define RELAY_OFF           0x01UL
33
#define RELAY_OFF           0x01
35
#define RELAY_ON            0x02UL
34
#define RELAY_ON            0x02
36
#define FAILSAFE_MODE       0x0FUL
35
#define FAILSAFE_MODE       0x0F
37
#define FAILSAFE_TRESHOLD   60  /* Degrees when nodeRelay goes into failsafe mode */
36
#define FAILSAFE_TRESHOLD   60  /* Degrees when nodeRelay goes into failsafe mode */
38
 
37
 
39
#define RELAY_CMD_ON        0x01UL
38
#define RELAY_CMD_ON        0x01
40
#define RELAY_CMD_OFF       0x02UL
39
#define RELAY_CMD_OFF       0x02
41
#define RELAY_CMD_TOGGLE    0x03UL
40
#define RELAY_CMD_TOGGLE    0x03
42
#define RELAY_CMD_STATUS    0x04UL
41
#define RELAY_CMD_STATUS    0x04
43
#define RELAY_CMD_RESET     0x05UL
42
#define RELAY_CMD_RESET     0x05
44
#define STATUS_SEND_PERIOD  10000 /* milliseconds */
43
#define STATUS_SEND_PERIOD  10000UL /* milliseconds */
45
#define FAILSAFE_SEND_PERIOD    10000 /* milliseconds */
44
#define FAILSAFE_SEND_PERIOD    10000UL /* milliseconds */
46
#define BOUNCE_TIME         10 /* milliseconds */
45
#define BOUNCE_TIME         10 /* milliseconds */
47
#define BUTTON1             1
46
#define BUTTON1             1
48
#define BUTTON2             2
47
#define BUTTON2             2
-
 
48
 
-
 
49
#define TRUE    1
-
 
50
#define FALSE   0
49
 
51
 
50
/*-------------------------------------------------------------------------
52
/*-------------------------------------------------------------------------
51
 * Global variables
53
 * Global variables
52
 * -----------------------------------------------------------------------*/
54
 * -----------------------------------------------------------------------*/
53
#if TWO_BUTTON_MODE
55
uint8_t relayStatus, failsafe_flag = FALSE, rxMsg_Data_bytes[8], msg_received = FALSE;
54
Can_Message_t txMsg_Button;
56
uint32_t boardTemperature = 0;
55
#endif
-
 
56
 
-
 
57
 
57
 
58
uint8_t relayStatus, failsafe_flag = 0;
-
 
59
uint32_t boardTemperature = 0;
-
 
60
Can_Message_t txMsg;
-
 
61
 
58
 
62
/*----------------------------------------------------------------------------
59
/*----------------------------------------------------------------------------
63
 * Functions
60
 * Functions
64
 * -------------------------------------------------------------------------*/
61
 * -------------------------------------------------------------------------*/
65
uint8_t relayOff();
62
uint8_t relayOff();
66
uint8_t relayOn();
63
uint8_t relayOn();
67
void relayFailsafe();
64
void relayFailsafe();
-
 
65
void sendStatus();
68
 
66
 
69
void can_receive(Can_Message_t *msg){
67
void can_receive(Can_Message_t *msg)
-
 
68
{ // CAN callback function
70
    uint32_t act;
69
    uint32_t act;
71
    uint32_t m, act_type, group, node;
70
    uint8_t m, act_type, group, node;
72
 
71
 
73
    if( ((msg->Id & CLASS_MASK)>>CLASS_MASK_BITS) == CLASS_ACT){
72
    if( ((msg->Id & CLASS_MASK)>>CLASS_MASK_BITS) == CLASS_ACT){
74
 
-
 
-
 
73
        // Actuator package
75
        act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
74
        act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
76
        act_type = (act & ACT_TYPE_MASK) >> ACT_TYPE_BITS;
75
        act_type =(uint8_t)((act & ACT_TYPE_MASK) >> ACT_TYPE_BITS);
77
        group = (act & ACT_GROUP_MASK) >> ACT_GROUP_BITS;
76
        group = (uint8_t)((act & ACT_GROUP_MASK) >> ACT_GROUP_BITS);
78
        node = (act & ACT_NODE_MASK) >> ACT_NODE_BITS;
77
        node = (uint8_t)((act & ACT_NODE_MASK) >> ACT_NODE_BITS);
79
 
78
 
80
        if( act_type == ACT_TYPE_RELAY && (group == GROUP_ID || node == NODE_ID) ){
79
        if( act_type == ACT_TYPE_RELAY && (group == GROUP_ID || node == NODE_ID) ){
81
            if(msg->Data.bytes[0] == RELAY_CMD_ON && !failsafe_flag){
-
 
82
                // Turn relay on
-
 
83
                relayStatus = relayOn();
-
 
84
 
-
 
85
            }else if(msg->Data.bytes[0] == RELAY_CMD_OFF && !failsafe_flag){
-
 
86
                // Turn relay off
-
 
87
                relayStatus = relayOff();
-
 
88
                txMsg.Id = 0x8000111UL; // FIXME
-
 
89
                bios->can_send(&txMsg);
-
 
90
 
-
 
91
            }else if(msg->Data.bytes[0] == RELAY_CMD_TOGGLE && !failsafe_flag){
-
 
92
                    // Toggle relay
-
 
93
                    if(relayStatus == RELAY_OFF){
-
 
94
                        relayStatus = relayOn();
-
 
95
                    }else{
-
 
96
                        relayStatus = relayOff();
-
 
97
                        txMsg.Id = 0x8000113UL; // FIXME
-
 
98
                        bios->can_send(&txMsg);
-
 
99
                    }
-
 
100
 
-
 
101
            }else if(msg->Data.bytes[0] == RELAY_CMD_STATUS && !failsafe_flag){
-
 
102
                // Send relay status to CAN
80
            // This is a message for this node
103
                boardTemperature = getTC1047temperature();
-
 
104
 
81
 
105
                if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
-
 
106
                    // Goto failsafe mode
-
 
107
                    relayFailsafe();
-
 
108
                }else{
-
 
109
                    // Transmitt node status
-
 
110
                    txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
-
 
111
                    txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
-
 
112
                    txMsg.Data.bytes[2] = relayStatus;
-
 
113
                    txMsg.Data.bytes[3] = 0;
-
 
114
                    txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
-
 
115
                    bios->can_send( &txMsg );
-
 
116
                }
-
 
117
            }else if(msg->Data.bytes[0] == RELAY_CMD_RESET){
82
            if(rxMsg_Data_bytes[0] == RELAY_CMD_RESET){
118
                // Return to normal operation
83
                // Return to normal operation
119
                failsafe_flag = 0;
84
                failsafe_flag = 0;
120
            }
85
            }
-
 
86
 
-
 
87
            for(m=0;m<(msg->DataLength);m++){
-
 
88
                rxMsg_Data_bytes[m] = msg->Data.bytes[m];
-
 
89
            }
-
 
90
            msg_received = TRUE; // Tell application that message has arrived
121
        }
91
        }
122
    }
92
    }
123
}
93
}
124
 
94
 
125
/*----------------------------------------------------------------------------
95
/*----------------------------------------------------------------------------
126
 * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
96
 * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
127
 * -------------------------------------------------------------------------*/
97
 * -------------------------------------------------------------------------*/
128
#if TWO_BUTTON_MODE
98
#if TWO_BUTTON_MODE
129
ISR( PCINT2_vect )
99
ISR( PCINT2_vect )
130
{
100
{
131
    /*
-
 
132
     * Auxiliary button pressed and released
-
 
133
     * Check time between press and release to eliminate bounces
-
 
134
     */
-
 
135
    static uint32_t buttonTime[2];
-
 
136
 
101
 
137
    txMsg_Button.RemoteFlag = 0;
-
 
138
    txMsg_Button.ExtendedFlag = 1;
-
 
139
 
-
 
140
    if( (PIND & (1<<PD6)) == 0){
-
 
141
        /* Button pressed */
-
 
142
        buttonTime[0] = Timebase_CurrentTime();
-
 
143
    }else if( (PIND & (1<<PD6)) == 1){
-
 
144
        if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
-
 
145
            /* No bounce, send message */
-
 
146
            txMsg_Button.Id = BUTTON_ID;
-
 
147
            txMsg_Button.DataLength = 1;
-
 
148
            txMsg_Button.Data.bytes[0] = BUTTON1;
-
 
149
            return;
-
 
150
        }else{
-
 
151
            /* Just bounces, ignore it */
-
 
152
            return;
-
 
153
        }
-
 
154
    }
-
 
155
    if( (PIND & (1<<PD7)) == 0){
-
 
156
        /* Button pressed */
-
 
157
        buttonTime[1] = Timebase_CurrentTime();
-
 
158
    }else if( (PIND & (1<<PD7)) == 1){
-
 
159
        if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
-
 
160
            /* No bounce, send message */
-
 
161
            txMsg_Button.Id = BUTTON_ID;
-
 
162
            txMsg_Button.DataLength = 1;
-
 
163
            txMsg_Button.Data.bytes[0] = BUTTON2;
-
 
164
            return;
-
 
165
        }else{
-
 
166
            /* Just bounces, ignore it */
-
 
167
            return;
-
 
168
        }
-
 
169
    }
-
 
170
}
102
}
171
#endif
103
#endif
172
 
104
 
173
/*-----------------------------------------------------------------------------
105
/*-----------------------------------------------------------------------------
174
 * Main Program
106
 * Main Program
175
 *---------------------------------------------------------------------------*/
107
 *---------------------------------------------------------------------------*/
176
int main(void) {
108
int main(void) {
177
 
109
 
178
    adcTemperatureInit();
-
 
179
 
-
 
180
#if TWO_BUTTON_MODE
-
 
181
#error two button mode not yet tested
-
 
182
    /*
-
 
183
     * Initialize buttons
-
 
184
     * It is possible to use ie. sensors instead
110
    uint32_t timeStamp = bios->timebase_get(), temp = timeStamp;
185
     * but then change this
-
 
186
     */
-
 
187
    // Set as input and enable pull-up
-
 
188
    DDRD &= ~( (1<<DDD6)|(1<<DDD7) );
-
 
189
    PORTD |= (1<<PD6)|(1<<PD7);
-
 
190
 
111
 
191
    // Enable IO-pin interrupt
-
 
192
    PCICR |= (1<<PCIE1);
-
 
193
    // Unmask PD6 and PD7
-
 
194
    PCMSK2 |= (1<<PCINT22) | (1<<PCINT23);
-
 
195
#endif
-
 
196
 
-
 
197
    // Control channel for relay
-
 
198
    DDRC |= (1<<DDC1);
112
    Can_Message_t txMsg;
199
 
-
 
200
    // Set up callback for CAN messages
-
 
201
//  bios->can_callback = &can_receive;
-
 
202
 
-
 
203
    txMsg.RemoteFlag = 0;
113
    txMsg.RemoteFlag = 0;
204
    txMsg.ExtendedFlag = 1;
114
    txMsg.ExtendedFlag = 1;
205
    txMsg.DataLength = 4;
115
    txMsg.DataLength = 4;
206
 
116
 
-
 
117
    adcTemperatureInit();
-
 
118
 
-
 
119
    // Set up callback for CAN messages
-
 
120
    bios->can_callback = &can_receive;
-
 
121
 
207
    sei();
122
    sei();
208
 
123
 
209
    // Turn relay off
124
    // Turn relay off
210
    relayStatus = relayOff();
125
    relayStatus = relayOff();
211
    txMsg.Id = 0x8000110UL; // FIXME
126
//  txMsg.Id = 0x8000110; // FIXME
212
    bios->can_send(&txMsg);
127
//  bios->can_send(&txMsg);
213
 
-
 
214
    uint32_t timeStamp = bios->timebase_get(), temp;
-
 
215
 
128
 
-
 
129
    // Main loop
-
 
130
    while (1) {
-
 
131
 
-
 
132
        if(msg_received && !failsafe_flag ){
216
 
133
 
-
 
134
            if( rxMsg_Data_bytes[0] == RELAY_CMD_ON ){
217
    // Main loop
135
                // Turn relay on
-
 
136
                relayStatus = relayOn();
-
 
137
 
-
 
138
            }else if(rxMsg_Data_bytes[0] == RELAY_CMD_OFF ){
-
 
139
                // Turn relay off
-
 
140
                relayStatus = relayOff();
-
 
141
 
-
 
142
            }else if(rxMsg_Data_bytes[0] == RELAY_CMD_TOGGLE ){
-
 
143
                    // Toggle relay
-
 
144
                    if(relayStatus == RELAY_OFF){
-
 
145
                        relayStatus = relayOn();
218
    while (1) {
146
                    }else{
-
 
147
                        relayStatus = relayOff();
-
 
148
                    }
-
 
149
 
-
 
150
            }else if(rxMsg_Data_bytes[0] == RELAY_CMD_STATUS ){
-
 
151
                // Send relay status to CAN
-
 
152
                sendStatus();
-
 
153
            }
-
 
154
            msg_received = FALSE;
-
 
155
        }
219
 
156
 
220
        temp = bios->timebase_get();
157
        temp = bios->timebase_get();
221
        if( temp - timeStamp >= STATUS_SEND_PERIOD ){
158
        if( temp - timeStamp >= STATUS_SEND_PERIOD ){
222
            timeStamp = temp;
159
            timeStamp = temp;
223
            // Send relay status to CAN
-
 
224
 
-
 
225
//          boardTemperature = getTC1047temperature();
-
 
226
 
-
 
227
//          if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
-
 
228
//              relayFailsafe();
160
/*          txMsg.Id = 0x8000111;
229
//          }else{
-
 
230
                txMsg.Data.bytes[0] = timeStamp & 0x000000FF; //boardTemperature & 0x00FF;
161
            txMsg.Data.bytes[0] = timeStamp & 0x000000FF;
231
                txMsg.Data.bytes[1] = (timeStamp & 0x0000FF00)>>8; //(boardTemperature & 0xFF00)>>8;
162
            txMsg.Data.bytes[0] = (timeStamp & 0x0000FF00)>>8;
232
                txMsg.Data.bytes[2] = (timeStamp & 0x00FF0000)>>16; //relayStatus;
163
            txMsg.Data.bytes[0] = (timeStamp & 0x00FF0000)>>16;
233
                txMsg.Data.bytes[3] = (timeStamp & 0xFF000000)>>24; //0;
164
            txMsg.Data.bytes[0] = (timeStamp & 0xFF000000)>>24;
234
                txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
-
 
235
                bios->can_send( &txMsg );
165
            bios->can_send(&txMsg);
-
 
166
*/          // Send relay status to CAN
236
//          }
167
            sendStatus();
237
        }
168
        }
238
    }
169
    }
239
    return 0;
170
    return 0;
240
}
171
}
241
 
172
 
242
uint8_t relayOff()
173
uint8_t relayOff()
243
{
174
{
244
    // Turn off relay
175
    // Turn off relay
245
    PORTC &= ~(1<<PC1);
176
    PORTC &= ~(1<<PC1);
246
    DDRC |= (1<<DDC1); // FIXME
177
    DDRC |= (1<<DDC1);
247
 
178
 
248
    return RELAY_OFF;
179
    return RELAY_OFF;
249
}
180
}
250
 
181
 
251
uint8_t relayOn()
182
uint8_t relayOn()
252
{
183
{
253
    // Turn on relay
184
    // Turn on relay
254
    DDRC &= ~(1<<DDC1); // FIXME
185
    DDRC &= ~(1<<DDC1);
255
    PORTC |= (1<<PC1);
186
    PORTC |= (1<<PC1);
256
 
187
 
257
    return RELAY_ON;
188
    return RELAY_ON;
258
}
189
}
259
 
190
 
260
void relayFailsafe()
191
void relayFailsafe()
261
{
192
{
262
    uint32_t timeStamp = 0;
193
    uint32_t failsafe_timeStamp, temp;
263
 
-
 
264
    relayStatus = relayOff();
194
    relayStatus = relayOff();
265
    failsafe_flag = 1;
195
    failsafe_flag = 1;
266
 
196
 
267
    while(1){
197
    while(1){
268
 
198
 
269
        if( !failsafe_flag ){
199
        if( !failsafe_flag ){
270
            // Return from failsafe mode
200
            // Return from failsafe mode
271
            return;
201
            return;
272
        }
202
        }
-
 
203
// TODO skicka med period
-
 
204
        sendStatus( );
-
 
205
    }
-
 
206
}
273
 
207
 
-
 
208
void sendStatus()
-
 
209
{
274
        if( bios->timebase_get() - timeStamp >= FAILSAFE_SEND_PERIOD ){
210
    uint32_t temperature;
275
            timeStamp = bios->timebase_get();
211
    Can_Message_t statusMsg;
276
            // Send relay status to CAN
212
    statusMsg.RemoteFlag = 0;
-
 
213
    statusMsg.ExtendedFlag = 1;
277
            boardTemperature = getTC1047temperature();
214
    statusMsg.DataLength = 4;
-
 
215
    statusMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
278
 
216
 
-
 
217
    temperature = getTC1047temperature();
-
 
218
    if( (int32_t)temperature >= FAILSAFE_TRESHOLD && !failsafe_flag ){
-
 
219
        // Goto failsafe mode
-
 
220
        relayFailsafe();
-
 
221
    }else{
-
 
222
        // Transmitt node status
279
            txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
223
        statusMsg.Data.bytes[0] = temperature & 0x00FF;
280
            txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
224
        statusMsg.Data.bytes[1] = (temperature & 0xFF00)>>8;
281
            txMsg.Data.bytes[2] = relayStatus;
225
        statusMsg.Data.bytes[2] = relayStatus;
282
            txMsg.Data.bytes[3] = FAILSAFE_MODE;
226
        statusMsg.Data.bytes[3] = failsafe_flag;
283
            txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
-
 
284
 
227
 
285
            bios->can_send( &txMsg );
228
        bios->can_send( &statusMsg );
286
        }
-
 
287
    }
229
    }
288
}
230
}
289
 
-