Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
351 eqlazer 1
/**
2
 * CAN Relay.
3
 *
4
 *
5
 * @date    2006-12-17
6
 * @author  Erik Larsson
7
 *
8
 *   ADC=Vin*1024/Vref
9
 *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
10
 *
11
 *  Transmitts: DATA: <temperature low byte> <temperature high byte> <relay status> <failsafe mode>
12
 *
13
 *
14
 */
15
 
16
#define TWO_BUTTON_MODE 0 /* If using two (or just one but nothing more) auxiliary buttons */
17
 
18
/*-----------------------------------------------------------------------------
19
 * Includes
20
 *---------------------------------------------------------------------------*/
21
/* system files */
22
#include <avr/io.h>
23
#include <avr/interrupt.h>
24
#include <stdio.h>
25
/* lib files */
26
#include <bios.h>
27
#include <tc1047.h>
28
#include <funcdefs.h>
29
 
30
/* defines */
352 eqlazer 31
#define GROUP_ID        0x01UL
351 eqlazer 32
 
360 eqlazer 33
#define RELAY_OFF           0x01
34
#define RELAY_ON            0x02
35
#define FAILSAFE_MODE       0x0F
351 eqlazer 36
#define FAILSAFE_TRESHOLD   60  /* Degrees when nodeRelay goes into failsafe mode */
37
 
360 eqlazer 38
#define RELAY_CMD_ON        0x01
39
#define RELAY_CMD_OFF       0x02
40
#define RELAY_CMD_TOGGLE    0x03
41
#define RELAY_CMD_STATUS    0x04
42
#define RELAY_CMD_RESET     0x05
43
#define STATUS_SEND_PERIOD  10000UL /* milliseconds */
44
#define FAILSAFE_SEND_PERIOD    10000UL /* milliseconds */
351 eqlazer 45
#define BOUNCE_TIME         10 /* milliseconds */
46
#define BUTTON1             1
47
#define BUTTON2             2
48
 
360 eqlazer 49
#define TRUE    1
50
#define FALSE   0
51
 
351 eqlazer 52
/*-------------------------------------------------------------------------
53
 * Global variables
54
 * -----------------------------------------------------------------------*/
360 eqlazer 55
uint8_t relayStatus, failsafe_flag = FALSE, rxMsg_Data_bytes[8], msg_received = FALSE;
56
uint32_t boardTemperature = 0;
351 eqlazer 57
 
354 eqlazer 58
 
351 eqlazer 59
/*----------------------------------------------------------------------------
60
 * Functions
61
 * -------------------------------------------------------------------------*/
62
uint8_t relayOff();
63
uint8_t relayOn();
64
void relayFailsafe();
360 eqlazer 65
void sendStatus();
351 eqlazer 66
 
360 eqlazer 67
void can_receive(Can_Message_t *msg)
68
{ // CAN callback function
351 eqlazer 69
    uint32_t act;
360 eqlazer 70
    uint8_t m, act_type, group, node;
351 eqlazer 71
 
72
    if( ((msg->Id & CLASS_MASK)>>CLASS_MASK_BITS) == CLASS_ACT){
360 eqlazer 73
        // Actuator package
351 eqlazer 74
        act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
360 eqlazer 75
        act_type =(uint8_t)((act & ACT_TYPE_MASK) >> ACT_TYPE_BITS);
76
        group = (uint8_t)((act & ACT_GROUP_MASK) >> ACT_GROUP_BITS);
77
        node = (uint8_t)((act & ACT_NODE_MASK) >> ACT_NODE_BITS);
351 eqlazer 78
 
79
        if( act_type == ACT_TYPE_RELAY && (group == GROUP_ID || node == NODE_ID) ){
360 eqlazer 80
            // This is a message for this node
351 eqlazer 81
 
360 eqlazer 82
            if(rxMsg_Data_bytes[0] == RELAY_CMD_RESET){
351 eqlazer 83
                // Return to normal operation
352 eqlazer 84
                failsafe_flag = 0;
351 eqlazer 85
            }
360 eqlazer 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
351 eqlazer 91
        }
92
    }
93
}
94
 
95
/*----------------------------------------------------------------------------
96
 * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
97
 * -------------------------------------------------------------------------*/
98
#if TWO_BUTTON_MODE
99
ISR( PCINT2_vect )
100
{
101
 
102
}
103
#endif
104
 
105
/*-----------------------------------------------------------------------------
106
 * Main Program
107
 *---------------------------------------------------------------------------*/
108
int main(void) {
109
 
360 eqlazer 110
    uint32_t timeStamp = bios->timebase_get(), temp = timeStamp;
351 eqlazer 111
 
360 eqlazer 112
    Can_Message_t txMsg;
113
    txMsg.RemoteFlag = 0;
114
    txMsg.ExtendedFlag = 1;
115
    txMsg.DataLength = 4;
351 eqlazer 116
 
360 eqlazer 117
    adcTemperatureInit();
351 eqlazer 118
 
119
    // Set up callback for CAN messages
360 eqlazer 120
    bios->can_callback = &can_receive;
351 eqlazer 121
 
122
    sei();
123
 
124
    // Turn relay off
125
    relayStatus = relayOff();
360 eqlazer 126
//  txMsg.Id = 0x8000110; // FIXME
127
//  bios->can_send(&txMsg);
351 eqlazer 128
 
129
    // Main loop
130
    while (1) {
131
 
360 eqlazer 132
        if(msg_received && !failsafe_flag ){
133
 
134
            if( rxMsg_Data_bytes[0] == RELAY_CMD_ON ){
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();
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
        }
156
 
354 eqlazer 157
        temp = bios->timebase_get();
158
        if( temp - timeStamp >= STATUS_SEND_PERIOD ){
159
            timeStamp = temp;
360 eqlazer 160
/*          txMsg.Id = 0x8000111;
161
            txMsg.Data.bytes[0] = timeStamp & 0x000000FF;
162
            txMsg.Data.bytes[0] = (timeStamp & 0x0000FF00)>>8;
163
            txMsg.Data.bytes[0] = (timeStamp & 0x00FF0000)>>16;
164
            txMsg.Data.bytes[0] = (timeStamp & 0xFF000000)>>24;
165
            bios->can_send(&txMsg);
166
*/          // Send relay status to CAN
167
            sendStatus();
351 eqlazer 168
        }
169
    }
170
    return 0;
171
}
172
 
173
uint8_t relayOff()
174
{
175
    // Turn off relay
176
    PORTC &= ~(1<<PC1);
360 eqlazer 177
    DDRC |= (1<<DDC1);
351 eqlazer 178
 
179
    return RELAY_OFF;
180
}
181
 
182
uint8_t relayOn()
183
{
184
    // Turn on relay
360 eqlazer 185
    DDRC &= ~(1<<DDC1);
351 eqlazer 186
    PORTC |= (1<<PC1);
187
 
188
    return RELAY_ON;
189
}
190
 
191
void relayFailsafe()
192
{
360 eqlazer 193
    uint32_t failsafe_timeStamp, temp;
351 eqlazer 194
    relayStatus = relayOff();
352 eqlazer 195
    failsafe_flag = 1;
351 eqlazer 196
 
197
    while(1){
198
 
352 eqlazer 199
        if( !failsafe_flag ){
351 eqlazer 200
            // Return from failsafe mode
201
            return;
202
        }
360 eqlazer 203
// TODO skicka med period
204
        sendStatus( );
205
    }
206
}
351 eqlazer 207
 
360 eqlazer 208
void sendStatus()
209
{
210
    uint32_t temperature;
211
    Can_Message_t statusMsg;
212
    statusMsg.RemoteFlag = 0;
213
    statusMsg.ExtendedFlag = 1;
214
    statusMsg.DataLength = 4;
215
    statusMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
351 eqlazer 216
 
360 eqlazer 217
    temperature = getTC1047temperature();
218
    if( (int32_t)temperature >= FAILSAFE_TRESHOLD && !failsafe_flag ){
219
        // Goto failsafe mode
220
        relayFailsafe();
221
    }else{
222
        // Transmitt node status
223
        statusMsg.Data.bytes[0] = temperature & 0x00FF;
224
        statusMsg.Data.bytes[1] = (temperature & 0xFF00)>>8;
225
        statusMsg.Data.bytes[2] = relayStatus;
226
        statusMsg.Data.bytes[3] = failsafe_flag;
351 eqlazer 227
 
360 eqlazer 228
        bios->can_send( &statusMsg );
351 eqlazer 229
    }
230
}