Subversion Repositories HomeAutomation

Rev

Rev 486 | Rev 498 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 486 Rev 493
1
/**
1
/**
2
 * CAN Relay.
2
 * CAN Relay.
3
 *
3
 *
4
 *
4
 *
5
 * @date    2006-12-17
5
 * @date    2006-12-17
6
 * @author  Erik Larsson
6
 * @author  Erik Larsson
7
 *
7
 *
8
 *   ADC=Vin*1024/Vref
8
 *   ADC=Vin*1024/Vref
9
 *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
9
 *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
10
 *
10
 *
11
 *  Transmitts: DATA: <temperature low byte> <temperature high byte> <relay status> <failsafe mode>
11
 *  Transmitts: DATA: <temperature low byte> <temperature high byte> <relay status> <failsafe mode>
12
 *
12
 *
13
 *
13
 *
14
 */
14
 */
15
 
15
 
16
#define TWO_BUTTON_MODE 0 /* If using two (or just one but nothing more) auxiliary buttons */
16
#define TWO_BUTTON_MODE 0 /* If using two (or just one but nothing more) auxiliary buttons */
17
 
17
 
18
/*-----------------------------------------------------------------------------
18
/*-----------------------------------------------------------------------------
19
 * Includes
19
 * Includes
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
/* lib files */
25
/* lib files */
26
#include <config.h>
26
#include <config.h>
27
#include <bios.h>
27
#include <bios.h>
28
#include <drivers/timer/timebase.h>
28
#include <drivers/timer/timebase.h>
29
//#include <funcdefs.h>
29
//#include <funcdefs.h>
30
 
30
 
31
/* defines */
31
/* defines */
32
#define RELAY_OFF           0x01
32
#define RELAY_OFF           0x01
33
#define RELAY_ON            0x02
33
#define RELAY_ON            0x02
34
#define FAILSAFE_MODE       0x0F
34
#define FAILSAFE_MODE       0x0F
35
#define FAILSAFE_TRESHOLD   0xFF  /* Degrees when nodeRelay goes into failsafe mode */
35
#define FAILSAFE_TRESHOLD   0xFF  /* Degrees when nodeRelay goes into failsafe mode */
36
 
36
 
37
#define RELAY_CMD_ON        0x01
37
#define RELAY_CMD_ON        0x01
38
#define RELAY_CMD_OFF       0x02
38
#define RELAY_CMD_OFF       0x02
39
#define RELAY_CMD_TOGGLE    0x03
39
#define RELAY_CMD_TOGGLE    0x03
40
#define RELAY_CMD_STATUS    0x04
40
#define RELAY_CMD_STATUS    0x04
41
#define RELAY_CMD_RESET     0x05
41
#define RELAY_CMD_RESET     0x05
42
#define STATUS_SEND_PERIOD  10000UL /* milliseconds */
42
#define STATUS_SEND_PERIOD  10000UL /* milliseconds */
43
#define FAILSAFE_SEND_PERIOD    10000UL /* milliseconds */
43
#define FAILSAFE_SEND_PERIOD    10000UL /* milliseconds */
44
#define BOUNCE_TIME         10 /* milliseconds */
44
#define BOUNCE_TIME         10 /* milliseconds */
45
#define BUTTON1             1
45
#define BUTTON1             1
46
#define BUTTON2             2
46
#define BUTTON2             2
-
 
47
 
-
 
48
#define THISRELAYID         NODE_ID     /* application software should not depend on the id of the physical node
-
 
49
                                            but for now lets do it like this */
47
 
50
 
48
#define APP_TYPE    CAN_APPTYPES_RELAY
51
#define APP_TYPE    CAN_APPTYPES_RELAY
49
#define APP_VERSION 0x0001
52
#define APP_VERSION 0x0001
50
 
53
 
51
/*-------------------------------------------------------------------------
54
/*-------------------------------------------------------------------------
52
 * Global variables
55
 * Global variables
53
 * -----------------------------------------------------------------------*/
56
 * -----------------------------------------------------------------------*/
54
uint8_t relayStatus, failsafe_flag = 0;
57
uint8_t relayStatus, failsafe_flag = 0;
55
uint32_t boardTemperature = 0;
58
uint32_t boardTemperature = 0;
56
 
59
 
57
volatile Can_Message_t rxMsg; // Message storage
60
volatile Can_Message_t rxMsg; // Message storage
58
volatile uint8_t rxMsgFull;   // Synchronization flag
61
volatile uint8_t rxMsgFull;   // Synchronization flag
59
 
62
 
60
 
63
 
61
/*----------------------------------------------------------------------------
64
/*----------------------------------------------------------------------------
62
 * Functions
65
 * Functions
63
 * -------------------------------------------------------------------------*/
66
 * -------------------------------------------------------------------------*/
64
uint8_t relayOff();
67
uint8_t relayOff();
65
uint8_t relayOn();
68
uint8_t relayOn();
66
void relayFailsafe();
69
void relayFailsafe();
67
void sendStatus();
70
void sendStatus();
68
 
71
 
69
void can_receive(Can_Message_t *msg)
72
void can_receive(Can_Message_t *msg)
70
{ // CAN callback function
73
{ // CAN callback function
71
    if (!rxMsgFull) {
74
    if (!rxMsgFull) {
72
        memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
75
        memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
73
        rxMsgFull = 1;
76
        rxMsgFull = 1;
74
    }
77
    }
75
}
78
}
76
 
79
 
77
/*----------------------------------------------------------------------------
80
/*----------------------------------------------------------------------------
78
 * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
81
 * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
79
 * -------------------------------------------------------------------------*/
82
 * -------------------------------------------------------------------------*/
80
#if TWO_BUTTON_MODE
83
#if TWO_BUTTON_MODE
81
ISR( PCINT2_vect )
84
ISR( PCINT2_vect )
82
{
85
{
83
 
86
 
84
}
87
}
85
#endif
88
#endif
86
 
89
 
87
/*-----------------------------------------------------------------------------
90
/*-----------------------------------------------------------------------------
88
 * Main Program
91
 * Main Program
89
 *---------------------------------------------------------------------------*/
92
 *---------------------------------------------------------------------------*/
90
int main(void) {
93
int main(void) {
91
 
94
 
92
    uint32_t timeStamp = Timebase_CurrentTime(), temp = timeStamp;
95
    uint32_t timeStamp = Timebase_CurrentTime(), temp = timeStamp;
93
 
96
 
94
    adcTemperatureInit();
97
    adcTemperatureInit();
95
 
98
 
96
    // Set up callback for CAN messages
99
    // Set up callback for CAN messages
97
    BIOS_CanCallback = &can_receive;
100
    BIOS_CanCallback = &can_receive;
98
 
101
 
99
    sei();
102
    sei();
100
   
103
   
101
    Timebase_Init();
104
    Timebase_Init();
102
 
105
 
103
    Can_Message_t txMsg;
106
    Can_Message_t txMsg;
104
    txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
107
    txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
105
    txMsg.DataLength = 4;
108
    txMsg.DataLength = 4;
106
    txMsg.RemoteFlag = 0;
109
    txMsg.RemoteFlag = 0;
107
    txMsg.ExtendedFlag = 1;
110
    txMsg.ExtendedFlag = 1;
108
    txMsg.Data.words[0] = APP_TYPE;
111
    txMsg.Data.words[0] = APP_TYPE;
109
    txMsg.Data.words[1] = APP_VERSION;
112
    txMsg.Data.words[1] = APP_VERSION;
110
    BIOS_CanSend(&txMsg);
113
    BIOS_CanSend(&txMsg);
111
 
114
 
112
    // Turn relay off
115
    // Turn relay off
113
    relayStatus = relayOff();
116
    relayStatus = relayOff();
114
 
117
 
115
    // Main loop
118
    // Main loop
116
    while (1) {
119
    while (1) {
117
 
120
 
118
        temp = Timebase_CurrentTime();
121
        temp = Timebase_CurrentTime();
119
        if( temp - timeStamp >= STATUS_SEND_PERIOD ){
122
        if( temp - timeStamp >= STATUS_SEND_PERIOD ){
120
            timeStamp = temp;
123
            timeStamp = temp;
121
            // Send relay status to CAN
124
            // Send relay status to CAN
122
            sendStatus();
125
            sendStatus();
123
        }
126
        }
124
 
127
 
125
        if (rxMsgFull) {
128
        if (rxMsgFull) {
126
            uint8_t acttype;
129
            uint8_t acttype;
127
            uint16_t servoid;
130
            uint16_t relayid;
128
       
131
       
129
            if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){
132
            if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){
130
                // Actuator package
133
                // Actuator package
131
                acttype =(uint8_t)((rxMsg.Id & CAN_MASK_ACT_FUNCC) >> CAN_SHIFT_ACT_FUNCC);
134
                acttype =(uint8_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
132
                servoid = (uint16_t)((rxMsg.Id & CAN_MASK_ACT_NID) >> CAN_SHIFT_ACT_NID);
135
                relayid = (uint16_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
133
               
136
               
134
                if ((acttype == ACT_FUNCC_RELAY) && (servoid == NODE_ID)) {
137
                if ((acttype == ACT_TYPE_RELAY) && (relayid == THISRELAYID)) {
135
                    // This is a message for this relay
138
                    // This is a message for this relay
136
                    if (rxMsg.Data.bytes[0] == RELAY_CMD_RESET) {
139
                    if (rxMsg.Data.bytes[0] == RELAY_CMD_RESET) {
137
                        // Return to normal operation
140
                        // Return to normal operation
138
                        failsafe_flag = 0;
141
                        failsafe_flag = 0;
139
                    }
142
                    }
140
                   
143
                   
141
                    if (!failsafe_flag) {
144
                    if (!failsafe_flag) {
142
                        if (rxMsg.Data.bytes[0] == RELAY_CMD_ON ){
145
                        if (rxMsg.Data.bytes[0] == RELAY_CMD_ON ){
143
                            // Turn relay on
146
                            // Turn relay on
144
                            relayStatus = relayOn();
147
                            relayStatus = relayOn();
145
           
148
           
146
                        } else if (rxMsg.Data.bytes[0] == RELAY_CMD_OFF ){
149
                        } else if (rxMsg.Data.bytes[0] == RELAY_CMD_OFF ){
147
                            // Turn relay off
150
                            // Turn relay off
148
                            relayStatus = relayOff();
151
                            relayStatus = relayOff();
149
           
152
           
150
                        } else if (rxMsg.Data.bytes[0] == RELAY_CMD_TOGGLE ){
153
                        } else if (rxMsg.Data.bytes[0] == RELAY_CMD_TOGGLE ){
151
                                // Toggle relay
154
                                // Toggle relay
152
                                if(relayStatus == RELAY_OFF){
155
                                if(relayStatus == RELAY_OFF){
153
                                    relayStatus = relayOn();
156
                                    relayStatus = relayOn();
154
                                }else{
157
                                }else{
155
                                    relayStatus = relayOff();
158
                                    relayStatus = relayOff();
156
                                }
159
                                }
157
           
160
           
158
                        }else if(rxMsg.Data.bytes[0] == RELAY_CMD_STATUS ){
161
                        }else if(rxMsg.Data.bytes[0] == RELAY_CMD_STATUS ){
159
                            // Send relay status to CAN
162
                            // Send relay status to CAN
160
                            sendStatus();
163
                            sendStatus();
161
                        }
164
                        }
162
                    }
165
                    }
163
                }
166
                }
164
            }
167
            }
165
            rxMsgFull = 0; //  
168
            rxMsgFull = 0; //  
166
 
169
 
167
        }
170
        }
168
       
171
       
169
    }
172
    }
170
    return 0;
173
    return 0;
171
}
174
}
172
 
175
 
173
uint8_t relayOff()
176
uint8_t relayOff()
174
{
177
{
175
    // Turn off relay
178
    // Turn off relay
176
    PORTC &= ~(1<<PC1);
179
    PORTC &= ~(1<<PC1);
177
    DDRC |= (1<<DDC1);
180
    DDRC |= (1<<DDC1);
178
 
181
 
179
    return RELAY_OFF;
182
    return RELAY_OFF;
180
}
183
}
181
 
184
 
182
uint8_t relayOn()
185
uint8_t relayOn()
183
{
186
{
184
    // Turn on relay
187
    // Turn on relay
185
    DDRC &= ~(1<<DDC1);
188
    DDRC &= ~(1<<DDC1);
186
    PORTC |= (1<<PC1);
189
    PORTC |= (1<<PC1);
187
 
190
 
188
    return RELAY_ON;
191
    return RELAY_ON;
189
}
192
}
190
 
193
 
191
void relayFailsafe()
194
void relayFailsafe()
192
{
195
{
193
    uint32_t failsafe_timeStamp, temp;
196
    uint32_t failsafe_timeStamp, temp;
194
    relayStatus = relayOff();
197
    relayStatus = relayOff();
195
    failsafe_flag = 1;
198
    failsafe_flag = 1;
196
 
199
 
197
    while(1){
200
    while(1){
198
 
201
 
199
        if( !failsafe_flag ){
202
        if( !failsafe_flag ){
200
            // Return from failsafe mode
203
            // Return from failsafe mode
201
            return;
204
            return;
202
        }
205
        }
203
// TODO skicka med period
206
// TODO skicka med period
204
        sendStatus( );
207
        sendStatus( );
205
    }
208
    }
206
}
209
}
207
 
210
 
208
void sendStatus()
211
void sendStatus()
209
{
212
{
210
    uint32_t temperature;
213
    uint32_t temperature;
211
    Can_Message_t statusMsg;
214
    Can_Message_t statusMsg;
212
    statusMsg.RemoteFlag = 0;
215
    statusMsg.RemoteFlag = 0;
213
    statusMsg.ExtendedFlag = 1;
216
    statusMsg.ExtendedFlag = 1;
214
    statusMsg.DataLength = 4;
217
    statusMsg.DataLength = 4;
215
    statusMsg.Id = ( CAN_SNS<<CAN_SHIFT_CLASS )|( SNS_FUNCC_RELAY_STATUS<<CAN_SHIFT_ACT_FUNCC )|( NODE_ID<<CAN_SHIFT_SNS_SID );
218
    statusMsg.Id = ( CAN_SNS<<CAN_SHIFT_CLASS )|( SNS_TYPE_RELAY_STATUS<<CAN_SHIFT_ACT_TYPE )|( NODE_ID<<CAN_SHIFT_SNS_SID );
216
   
219
   
217
    temperature = getTC1047temperature();
220
    temperature = getTC1047temperature();
218
    if( (int32_t)temperature >= FAILSAFE_TRESHOLD && !failsafe_flag ){
221
    if( (int32_t)temperature >= FAILSAFE_TRESHOLD && !failsafe_flag ){
219
        // Goto failsafe mode
222
        // Goto failsafe mode
220
        relayFailsafe();
223
        relayFailsafe();
221
    }else{
224
    }else{
222
        // Transmitt node status
225
        // Transmitt node status
223
        statusMsg.Data.bytes[0] = temperature & 0x00FF;
226
        statusMsg.Data.bytes[0] = temperature & 0x00FF;
224
        statusMsg.Data.bytes[1] = (temperature & 0xFF00)>>8;
227
        statusMsg.Data.bytes[1] = (temperature & 0xFF00)>>8;
225
        statusMsg.Data.bytes[2] = relayStatus;
228
        statusMsg.Data.bytes[2] = relayStatus;
226
        statusMsg.Data.bytes[3] = failsafe_flag;
229
        statusMsg.Data.bytes[3] = failsafe_flag;
227
 
230
 
228
        BIOS_CanSend( &statusMsg );
231
        BIOS_CanSend( &statusMsg );
229
    }
232
    }
230
}
233
}
231
 
234